IOC 依赖注入 复习(自用)

本文详细介绍了如何在Spring Boot应用中使用ClassPathXmlApplicationContext实现BeanFactory,包括XML配置文件的解析、依赖注入的过程以及beanMap的使用。通过实例演示了如何通过id和ref属性进行bean对象的注入。
摘要由CSDN通过智能技术生成

依赖注入与beanMap

package com.kerwin.myssm.ioc;

import com.kerwin.myssm.util.StringUtils;
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<String,Object>();

    //这里给个默认值
    String path="applicationContext.xml";

    //老师说过 框架都是用无参构造去反射的,如果不写无参构造,框架就会报错
    //我可能需要无参构造去 用来反射,但是我这个月无参构造没有用,我需要调用下面的有参构造,
    //所以只能这么写了

    public ClassPathXmlApplicationContext() {
        this("applicationContext.xml");
    }

    public ClassPathXmlApplicationContext(String path) {
        if(StringUtils.isNull(path)){
            throw new RuntimeException("ICO配置文件参数出错");
        }
        InputStream resourceAsStream = getClass().getClassLoader().getResourceAsStream(path);
        //1、创建DocumentBuilderFactory
        DocumentBuilderFactory documentBuilderFactory = DocumentBuilderFactory.newInstance();
        //2、创建DocumentBuilder对象
        DocumentBuilder documentBuilder = null;
        try {
            //3、创建Document对象
            documentBuilder = documentBuilderFactory.newDocumentBuilder();
            Document document = documentBuilder.parse(resourceAsStream);
            //4、获取所有bean节点
            //根据标签名  根据 bean标签,来获取 一个 node集合
            NodeList beanList = document.getElementsByTagName("bean");
            //然后循环这个集合


            for (int i = 0; i < beanList.getLength(); i++) {
                //这里面不叫get,叫item
                Node beanNode = beanList.item(i);
                if (beanNode.getNodeType() == Node.ELEMENT_NODE) {
                    //这个是 向上转型,用子类里面的方法
                    Element beanElement = (Element) beanNode;

                    String id = beanElement.getAttribute("id");
                    String className = beanElement.getAttribute("class");

                    //id对应实例对象
                    Class<?> aClass = Class.forName(className);

                    Object  beanObj = aClass.newInstance();


                    //把值放进去之后,再往集合里面放
                    beanMap.put(id, beanObj);
                    //我觉的要从这里开始,毕竟我要从map里面取对象

                }
            }
            //这里是依赖注入

            for (int i = 0; i < beanList.getLength(); i++) {
                //取出集合里的每一个node
                Node item = beanList.item(i);
                if (item.getNodeType() == Node.ELEMENT_NODE) {
                    Element element = (Element) item;
                    //取出每一个node的子node List
                    NodeList childNodes = element.getChildNodes();
                    //如果这个node里面的子node List 长度不为0  就是有子node
                    if(childNodes.getLength()!=0){
                        //注意这里的  element.getAttribute("id");
                        //是上面第79行取出来的 item 转换的 父node
                        //根据这个父node id去 beanMap里面去 取值
                        String objectId = element.getAttribute("id");
                        Object thisObj = beanMap.get(objectId);

                        //这段就是循环子node集合
                        for (int j = 0; j < childNodes.getLength(); j++) {
                            //获取每一个子node
                            Node item1 = childNodes.item(j);
                            //如果子node 的 name=property
                            /**
                             * <beans>
                             *     <bean id="user" class="com.kerwin.controller.UserController">
                             *         这个是子node 因为是标签node 所以nodeName=property
                             *         <property name="userService" ref="UserService"/>
                             *     </bean>
                             */
                            if (item1.getNodeType() == Node.ELEMENT_NODE&&item1.getNodeName().equals("property")) {
                                Element element1=(Element) item1;
                                String propertyName = element1.getAttribute("name");
                                //这个是引用  指向 的 属性,就是我需要耦合的那个
                                String propertyRef = element1.getAttribute("ref");

                                //这个beanObj 不能找错了
                                //是父id  指向的类
                                Class<?> aClass = thisObj.getClass();
                                //取得这种东西 private UserService userService=null;
                                Field declaredField = aClass.getDeclaredField(propertyName);
                                declaredField.setAccessible(true);
                                
                                //取得 子node 指向beanMap 集合里面的 obj
                                Object beanObject = beanMap.get(propertyRef);
                                //这步值应该就赋值进去了
                                //依赖注入
                                declaredField.set(thisObj,beanObject);

                            }
                        }
                    }

                }

            }

        } catch (ParserConfigurationException | IOException | SAXException | ClassNotFoundException | InstantiationException | IllegalAccessException e) {
            e.printStackTrace();

        } catch (NoSuchFieldException e) {
            e.printStackTrace();
        }
    }

    @Override
    public Object getBean(String name) {

        Object o = beanMap.get(name);
        return o;
    }
}

ioc需要的参数名

<build>
    <plugins>
      <plugin>

        <artifactId>maven-compiler-plugin</artifactId>
        <version>3.8.0</version>
        <configuration>
          <source>1.8</source>
          <target>1.8</target>

          <encoding>utf8</encoding>
          <compilerArgs>
            <arg>-parameters</arg>
          </compilerArgs>

        </configuration>
      </plugin>
      </build>
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值