ICode9

精准搜索请尝试: 精确搜索
首页 > 编程语言> 文章详细

JavaWeb学习-MVC

2022-07-22 20:03:19  阅读:150  来源: 互联网

标签:beanObj JavaWeb FruitServiceImpl DAO 学习 bean MVC public fruitService


 一、MVC概念

1. MVC : Model(模型)、View(视图)、Controller(控制器)

视图层:用于做数据展示以及和用户交互的一个界面
控制层:能够接受客户端的请求,具体的业务功能还是需要借助于模型组件来完成
模型层:模型分为很多种:有比较简单的pojo/vo(value object),有业务模型组件,有数据访问层组件。

 1)pojo/vo : 值对象模型                 2)DAO : 数据访问对象模型
 3)BO : 业务对象模型                   4)DTO:数据传输对象模型

2. 区分业务对象和数据访问对象

  1. DAO中的方法都是单精度方法或者称之为细粒度方法。什么叫单精度?一个方法只考虑一个操作,比如添加,那就是insert操作、查询那就是select操作…
  2. BO中的方法属于业务方法或者称之为粗粒度方法,而实际的业务是比较复杂的,因此业务方法的粒度是比较粗的。

例如:

注册这个功能属于业务功能,也就是说注册这个方法属于业务方法。
那么这个业务方法中包含了多个DAO方法。也就是说注册这个业务功能需要通过多个DAO方法的组合调用,从而完成注册功能的开发。
注册举例:

  1)检查用户名是否已经被注册 - DAO中的select操作
  2)向用户表新增一条新用户记录 - DAO中的insert操作
  3)向用户积分表新增一条记录(新用户默认初始化积分100分) - DAO中的insert操作
  4)向系统消息表新增一条记录(某某某新用户注册了,需要根据通讯录信息向他的联系人推送消息) - DAO中的insert操作
  5)向系统日志表新增一条记录(某用户在某IP在某年某月某日某时某分某秒某毫秒注册) - DAO中的insert操作
  6)…

  3. 在系统中添加业务层组件。(FruitService 调用FruitDao)图示:

public class FruitServiceImpl implements FruitService {
    private FruitDAO fruitDAO = new FruitDAOImpl();
    @Override
    public List<Fruit> getFruitList() {
        return fruitDAO.getFruitList();
    }

    @Override
    public Fruit getFruitById(int fid) {
        return fruitDAO.getFruitById(fid);
    }
}
public class FruitController {
    private FruitService fruitService = new FruitServiceImpl();
    //调用改为 fruitService.XXX
}

二、MVC-IOC

1. 耦合/依赖:

  在软件系统中,层与层之间是存在依赖的。我们也称之为耦合。

      我们系统架构或者是设计的一个原则是: 高内聚低耦合。层内部的组成应该是高度聚合的,而层与层之间的关系应该是低耦合的,最理想的情况0耦合(就是没有耦合)

实现下层改动不会影响上层(比如:删掉serviceImpl不会出错)

代码实现

1)配置文件

<beans>
    <!--1. 先描述需要什么组件
        2. 再描述组件与组件之间的依赖关系-->
    <bean id ="fruitDAO" class="com.fruits.dao.Impl.FruitDAOImpl">

    </bean>
    <bean id ="fruitService" class="com.fruits.ser.impl.FruitServiceImpl">
        <!-- property 标签用来表示属性:name表示属性名,ref表示引用其他bean的id值 -->
        <!-- FruitServiceImpl需要DAO: private FruitDAO fruitDAO = new FruitDAOImpl();
        所以  name 就是FruitServiceImpl中需要的属性名  而 ref 就引用到 某个bean的id:fruitDAO
        -->
        <property name="fruitDAO" ref="fruitDAO"></property>
    </bean>
    <bean id="fruit" class="com.fruits.controller.FruitController">
        <property name="fruitService" ref="fruitService"></property>
    </bean>
</beans>

2)创建一个Bean工厂,用来实现根据bean中的id获得class对象

package com.fruits.io;

public interface BeanFactory {
    Object getBean(String id); //根据bean中的id 获得class对象
}

实现类

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 beanNodeList = document.getElementsByTagName("bean");
            for (int i = 0; i < beanNodeList.getLength(); i++) {
                Node beanNode = beanNodeList.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);
                }
            }
            //5. 组装bean之间的依赖关系
            for (int i = 0; i < beanNodeList.getLength(); i++) {
                Node beanNode = beanNodeList.item(i);
                if (beanNode.getNodeType() == Node.ELEMENT_NODE) {
                    Element beanElement = (Element) beanNode;
                    String beanId = beanElement.getAttribute("id"); //fruitService
                    NodeList beanChildNodesList = beanElement.getChildNodes();
                    for (int j = 0; j < beanChildNodesList.getLength(); j++) {
                        Node beanChildNode  = beanChildNodesList.item(j);
                        if(beanChildNode.getNodeType()==Node.ELEMENT_NODE && "property".equals(beanChildNode.getNodeName())){
                            Element propertyElement = (Element)beanChildNode;
                            String propertyName = propertyElement.getAttribute("name");  //  propertyName=fruitDAO
                            String propertyRef = propertyElement.getAttribute("ref");  // propertyRef=fruitDAO
                            //1)找到propertyRef对应的实例
                            Object refObj = beanMap.get(propertyRef);  //refObj = com.fruits.dao.Impl.FruitDAOImpl
                            //2)将refObj设置到当前bean对应的实例的property属性上去
                            Object beanObj = beanMap.get(beanId);  // beanObj = com.fruits.ser.impl.FruitServiceImpl
                            Class beanClass = beanObj.getClass(); // beanClass = FruitServiceImpl
                            Field propertyField = beanClass.getDeclaredField(propertyName); //获取beanClass 中与propertyName有关的属性 propertyField =  private FruitDAO fruitDAO
                            propertyField.setAccessible(true);
                            propertyField.set(beanObj,refObj);  //将refObj设置到beanObj对应的propertyField中去
                        }                          //refObj = FruitDAOImpl  beanObj =  FruitServiceImpl  propertyField = fruit
                    }
                }
            }
        } catch (IOException e) {
            e.printStackTrace();
        } catch (InstantiationException e) {
            e.printStackTrace();
        } catch (ParserConfigurationException e) {
            e.printStackTrace();
        } catch (IllegalAccessException e) {
            e.printStackTrace();
        } catch (SAXException e) {
            e.printStackTrace();
        } catch (ClassNotFoundException e) {
            e.printStackTrace();
        } catch (NoSuchFieldException e) {
            e.printStackTrace();
        }
    }
    @Override
    public Object getBean(String id) {
        return beanMap.get(id);
    }
}

3) FruitServiceImpl

public class FruitServiceImpl implements FruitService {
    private FruitDAO fruitDAO = null;
    @Override
    public List<Fruit> getFruitList() {
        return fruitDAO.getFruitList();
    }
}

4)FruitController

public class FruitController {
    private FruitService fruitService = null;
}

2. IOC-控制反转 / DI - 依赖注入

 控制反转:

    1) 之前在Servlet中,我们创建service对象 , FruitService fruitService = new FruitServiceImpl();
       这句话如果出现在servlet中的某个方法内部,那么这个fruitService的作用域(生命周期)应该就是这个方法级别;
       如果这句话出现在servlet的类中,也就是说fruitService是一个成员变量,那么这个fruitService的作用域(生命周期)应该就是这个servlet实例级别

    2) 之后我们在applicationContext.xml中定义了这个fruitService。然后通过解析XML,产生fruitService实例,存放在beanMap中,这个beanMap在一个BeanFactory中
       因此,我们转移(改变)了之前的service实例、dao实例等等他们的生命周期。控制权从程序员转移到BeanFactory。这个现象我们称之为控制反转

    依赖注入:

    1) 之前我们在控制层出现代码:FruitService fruitService = new FruitServiceImpl();
       那么,控制层和service层存在耦合。

    2) 之后,我们将代码修改成FruitService fruitService = null ;
       然后,在配置文件中配置:
       <bean id="fruit" class="FruitController">
            <property name="fruitService" ref="fruitService"/>
       </bean>

标签:beanObj,JavaWeb,FruitServiceImpl,DAO,学习,bean,MVC,public,fruitService
来源: https://www.cnblogs.com/Joyce-mi7/p/16505020.html

本站声明: 1. iCode9 技术分享网(下文简称本站)提供的所有内容,仅供技术学习、探讨和分享;
2. 关于本站的所有留言、评论、转载及引用,纯属内容发起人的个人观点,与本站观点和立场无关;
3. 关于本站的所有言论和文字,纯属内容发起人的个人观点,与本站观点和立场无关;
4. 本站文章均是网友提供,不完全保证技术分享内容的完整性、准确性、时效性、风险性和版权归属;如您发现该文章侵犯了您的权益,可联系我们第一时间进行删除;
5. 本站为非盈利性的个人网站,所有内容不会用来进行牟利,也不会利用任何形式的广告来间接获益,纯粹是为了广大技术爱好者提供技术内容和技术思想的分享性交流网站。

专注分享技术,共同学习,共同进步。侵权联系[81616952@qq.com]

Copyright (C)ICode9.com, All Rights Reserved.

ICode9版权所有