mvc-ioc实现

mvc-ioc实现

IOC(Inversion of Control):控制反转
    1) 耦合/依赖
      依赖指的是某某某离不开某某某
      在软件系统中,层与层之间是存在依赖的。我们也称之为耦合。
      我们系统架构或者是设计的一个原则是: 高内聚低耦合。
      层内部的组成应该是高度聚合的,而层与层之间的关系应该是低耦合的,最理想的情况0耦合(就是没有耦合)
    2) IOC - 控制反转 / DI - 依赖注入

BeanFactory 接口

public interface BeanFactory {
    Object getBean(String id);
}

ClassPathXmlApplicationContext 类

public class ClassPathXmlApplicationContext implements BeanFactory {

    private Map<String, Object> beanMap = new HashMap<>();

    public ClassPathXmlApplicationContext() {
        try {
            InputStream inputStream = getClass().getClassLoader().getResourceAsStream("applicationContext.xml");
            //1.创建DocumentBuilderFactory对象
            DocumentBuilderFactory documentBuilderFactory = DocumentBuilderFactory.newInstance();
            //2.创建DocumentBuilder对象
            DocumentBuilder documentBuilder = documentBuilderFactory.newDocumentBuilder();
            //3.创建Document对象
            Document document = documentBuilder.parse(inputStream);

            //4.获取所有的bean节点
            NodeList beanNodeLists = document.getElementsByTagName("bean");
            for (int i = 0; i < beanNodeLists.getLength(); i++) {
                Node beanNode = beanNodeLists.item(i);
                //判断该节点的类型是否等于元素节点
                if (beanNode.getNodeType() == Node.ELEMENT_NODE) {
                    Element beanElement = (Element) beanNode;
                    String beanId = beanElement.getAttribute("id");
                    String className = beanElement.getAttribute("class");
                    Class beanClass = Class.forName(className);
                    //创建bean实例
                    Object beanObj = beanClass.newInstance();
                    //将bean实例对象保存到map容器中
                    beanMap.put(beanId, beanObj);
                    //到目前为止,此处需要注意的是:bean和bean之间的依赖关系还没有设置
                }
            }
            //5.组装bean之间的依赖关系
            for (int i = 0; i < beanNodeLists.getLength(); i++) {
                Node beanNode = beanNodeLists.item(i);
                //判断该节点的类型是否等于元素节点
                if (beanNode.getNodeType() == Node.ELEMENT_NODE) {
                    Element beanElement = (Element) beanNode;
                    String beanId = beanElement.getAttribute("id");
                    NodeList beanChildNodeList = beanElement.getChildNodes();
                    for (int j = 0; j < beanChildNodeList.getLength(); j++) {
                        Node beanChildNode = beanChildNodeList.item(j);
                        if (beanChildNode.getNodeType() == Node.ELEMENT_NODE && "property".equals(beanChildNode.getNodeName())) {
                            Element propertyElement = (Element) beanChildNode;
                            String propertyName = propertyElement.getAttribute("name");
                            String propertyRef = propertyElement.getAttribute("ref");
                            //1.找到propertyRef对应的实例
                            Object refObj = beanMap.get(propertyRef);
                            //2.将refObj设置到当前bean对应的实例的property属性上去
                            Object beanObj = beanMap.get(beanId);
                            Class beanClass = beanObj.getClass();
                            Field propertyField = beanClass.getDeclaredField(propertyName);
                            propertyField.setAccessible(true);
                            propertyField.set(beanObj, refObj);
                        }
                    }
                }
            }
        } catch (ParserConfigurationException e) {
            e.printStackTrace();
        } catch (SAXException e) {
            e.printStackTrace();
        } catch (IOException e) {
            e.printStackTrace();
        } catch (IllegalAccessException e) {
            e.printStackTrace();
        } catch (InstantiationException e) {
            e.printStackTrace();
        } catch (ClassNotFoundException e) {
            e.printStackTrace();
        } catch (NoSuchFieldException e) {
            e.printStackTrace();
        }
    }

    @Override
    public Object getBean(String id) {
        return beanMap.get(id);
    }
}

FruitController 类

//FruitServlet 改名为 FruitController
public class FruitController{

    private FruitService fruitService = null;

    private String update(Integer fid,String fname,Integer price,Integer fcount,String remark){
        //3.执行更新
        fruitService.updateFruit(new Fruit(fid, fname, price, fcount, remark));
        //4.资源跳转
        //super.processTemplate("index",request,response);
        //request.getRequestDispatcher(index.html).forward(request,response);
        //此处需要重定向,目的是重新给IndexServlet发请求,重新获取fruitList,然后覆盖到session
        //这样index.html页面上显示的session中的数据才是最新的
        //response.sendRedirect("fruit.do");
        return "redirect:fruit.do";
    }

    private String edit(Integer fid,HttpServletRequest request){
        if (fid != null) {
            Fruit fruit = fruitService.getFruitByFid(fid);
            request.setAttribute("fruit", fruit);
            //super.processTemplate("edit", request, response);
            return "edit";
        }
        return "error";
    }

    private String del(Integer fid){
        if (fid != null) {
            fruitService.delFruit(fid);
            //response.sendRedirect("fruit.do");
            return "redirect:fruit.do";
        }
        return "error";
    }

    private String add(String fname,Integer price,Integer fcount,String remark){
        Fruit fruit = new Fruit(0, fname, price, fcount, remark);
        fruitService.addFruit(fruit);
        //response.sendRedirect("fruit.do");
        return "redirect:fruit.do";
    }

    private String index(String oper,String keyword,Integer pageNo,HttpServletRequest request){

        HttpSession session = request.getSession();

        if (pageNo == null){
            pageNo = 1;
        }

        //如果oper != null 说明是通过表单的查询按钮点击过来的
        //如果oper是空的,说明不是通过表单的查询按钮点击过来的
        if (StringUtil.isNotEmpty(oper) && "search".equals(oper)) {
            //说明是点击表单查询发送过来的请求
            //此时,pageNo应该还原为1,keyword应该从请求参数获取
            pageNo = 1;
            //如果keyword为null,需要设置为空字符串"",否则查询时会拼接成 %null%
            //我们期望的是 %%,就是查询所有的数据
            if (StringUtil.isEmpty(keyword)) {
                keyword = "";
            }
            //将 keyword 保存(覆盖)到session中
            session.setAttribute("keyword", keyword);
        } else {
            //说明此处不是点击表单查询发送过来的请求(比如点击下面的上一页下一页或者直接在地址栏输入网址)
            //此时keyword应该从session作用域获取
            //如果不是点击的查询按钮,那么查询是基于session中保存的现有的keyword进行查询
            Object keywordobj = session.getAttribute("keyword");
            if (keywordobj != null) {
                keyword = (String) keywordobj;
            } else {
                keyword = "";
            }
        }

        //重新更新当前页的值
        session.setAttribute("pageNo", pageNo);

        List<Fruit> fruitList = fruitService.getFruitList(keyword, pageNo);
        session.setAttribute("fruitList", fruitList);

        //总记录条数
        int pageCount = fruitService.getPageCount(keyword);
        /*
        总记录条数      总页数
        1                   1
        5                   1
        6                   2
        10                  2
        11                  3
        fruitCount          (fruitCount+5-1)/5
         */

        session.setAttribute("pageCount", pageCount);

        //此处的视图名称是index
        //那么thymeleaf会将这个 逻辑视图 名称对应到 物理视图 名称上去
        //        //逻辑视图名称:index
        //物理视图名称:      viw-prefix + 逻辑视图名称 +view-suffix
        //所以真实的视图名称是:   /            index        .html
        //super.processTemplate("index", request, response);
        return "index";
    }
}

FruitService 接口

public interface FruitService {
    //获取指定页面的库存列表信息
    List<Fruit> getFruitList(String keyword, Integer pageNo);

    //添加库存记录信息
    void addFruit(Fruit fruit);

    //根据id查看指定库存记录
    Fruit getFruitByFid(Integer fid);

    //删除特定库存记录
    void delFruit(Integer fid);

    //修改特定库存记录
    void updateFruit(Fruit fruit);

    //获取总页数
    Integer getPageCount(String keyword);

}

FruitServiceImpl 类

public class FruitServiceImpl implements FruitService{

    private FruitDAO fruitDAO = null;

    @Override
    public List<Fruit> getFruitList(String keyword, Integer pageNo) {
        return fruitDAO.getFruitList(keyword,pageNo);
    }

    @Override
    public void addFruit(Fruit fruit) {
        fruitDAO.addFruit(fruit);
    }

    @Override
    public Fruit getFruitByFid(Integer fid) {
        return fruitDAO.getFruitByFid(fid);
    }

    @Override
    public void delFruit(Integer fid) {
        fruitDAO.delFruit(fid);
    }

    @Override
    public void updateFruit(Fruit fruit) {
        fruitDAO.updateFruit(fruit);
    }

    @Override
    public Integer getPageCount(String keyword) {
        int count = fruitDAO.getFruitCount(keyword);
        int pageCount = (count + 5 - 1) / 5;
        return pageCount;
    }
}

applicationContext.xml

<?xml version="1.0" encoding="utf-8"?>

<beans>
    <bean id="fruitDAO" class="com.atguigu.fruit.dao.impl.FruitDAOImpl"/>
    <bean id="fruitService" class="com.atguigu.fruit.service.impl.FruitServiceImpl">
        <!-- property标签用来表示属性;name表示属性名;ref表示引用其它bean的id值 -->
        <property name="fruitDAO" ref="fruitDAO"/>
    </bean>
    <!-- 这个bean标签的作用是 将来servletpath中涉及的名字对应的是fruit,那么就要FruitController这个类来处理 -->
    <bean id="fruit" class="com.atguigu.fruit.controllers.FruitController">
        <property name="fruitService" ref="fruitService"/>
    </bean>
</beans>

<!--

Node节点
    Element节点
    Text 文本节点

<sname>jim</sname>

-->
<!--
1.概念
    HTML : 超文本标记语言
    XML : 可扩展的标记语言
    HTML是XML的一个子集

2.XML包含三个部分:
    1) XML声明 , 而且声明这一行代码必须在XML文件的第一行
    2) DTD 文档类型定义
    3) XML正文
-->

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值