降低层与层之间的耦合度

将各层之间的依赖对象赋值为null,降低耦合。

1、将层与层之间的依赖写在配置文件中,application.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 id="fruit" class="com.atguigu.fruit.controllers.FruitController">
        <property name="fruitService" ref="fruitService"/>
    </bean>
</beans>
<!--
Node 节点
    Element 元素节点
    Text 文本节点
<sname>jim</sname>
-->

 配置文件中id=fruitDAO告诉应用程序fruitDAO对象所对应的是FruitDAOImpl,同理fruitService对象对应的类是FruitServiceImpl。

property标签中,ref="fruitDAO"表示引用其他bean标签中id=fruitDAO所对应的类(例如FruitServiceeImpl),name="fruitService"表示该类中有一个对象命名为fruitService。

2、创建beanFactory接口,在接口中创建getBean方法,创建classPatchApplicationContext类实现beanFactory接口,在构造方法中创建读取配置文件信息,并存放在Map集合中。

beanFactory接口:
 


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

classPatchApplicationContext类:


import org.w3c.dom.Document;
import org.w3c.dom.Element;
import org.w3c.dom.Node;
import org.w3c.dom.NodeList;
import org.xml.sax.SAXException;

import javax.xml.parsers.DocumentBuilder;
import javax.xml.parsers.DocumentBuilderFactory;
import javax.xml.parsers.ParserConfigurationException;
import java.io.IOException;
import java.io.InputStream;
import java.lang.reflect.Field;
import java.util.HashMap;
import java.util.Map;

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容器中,到目前为止,bean与bean之间的依赖关系还有设置
                    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 ;//获取bean节点
                    String beanId =  beanElement.getAttribute("id");
                    NodeList beanChildNodeList=beanElement.getChildNodes();//获取当前bean节点下的子节点(property)
                    //遍历子节点,找出元素节点切元素节点名称为property
                    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 beanClazz=beanObj.getClass();
                            Field propertyField=beanClazz.getDeclaredField(propertyName);
                            propertyField.setAccessible(true);
                            propertyField.set(beanObj,refObj);
                        }
                    }


                    String className = beanElement.getAttribute("class");
                    Class beanClass = Class.forName(className);
                    //创建bean实例
                    Object beanObj = beanClass.newInstance() ;
                    //将bean实例对象保存到map容器中,到目前为止,bean与bean之间的依赖关系还有设置
                    beanMap.put(beanId , beanObj) ;
                }
            }
        } 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) {
            throw new RuntimeException(e);
        }
    }
    @Override
    public Object getBean(String id) {
        return beanMap.get(id);
    }
}

3、在中央控制器类中创建classPatchApplicationContext类对象,在初始化方法中实例化classPatchApplicationContext类对象,方便获取Map集合中的数据。


    private BeanFactory beanFactory;

    public DispatcherServlet(){
    }

    public void init() throws ServletException {
        super.init();
        beanFactory=new ClassPathXmlApplicationContext();
    }

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

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值