Spring Ioc底层实现

2021-05-29 07:00

阅读:498

标签:eth   uppercase   根据   version   底层实现   new   element   declared   book   

原理和步骤

  1. Ioc容器的实现主要依赖的是xml解析和Java反射。
  2. 步骤:读取配置文件 -> 将其逐层“剥开”,获取各项属性 -> 通过各属性配合反射生成对象 -> 将其放入容器中,以供调用

具体实现

  • 实体类 Book
@Data
@AllArgsConstructor
@NoArgsConstructor
public class Book {
    private Integer id;
    private String name;
    private Double price;
}
  • 配置文件 spring.xml
  • xml解析使用的是Dom4j,加入maven依赖
dom4j
    dom4j
    1.1
  • MyClassPathXmlApplicationContext。需要实现接口ApplicationContext,着重重写以下方法:
    • 创建容器 Map
    private final Map iocMap;
    
    • 重写构造方法 此处将解析xml的步骤写在自定义方法parseXML
    public MyClassPathXmlApplicationContext(String path) {
        iocMap = new HashMap();
        parseXML(path);
    }
    
    • parseXML()
    //使用Dom4j进行xml解析
    public void parseXML(String path) {
        SAXReader saxReader = new SAXReader();
        try {
            //定义文档
            Document document = saxReader.read("src/main/resources/" + path);
            //获取根节点,即
            Element beans = document.getRootElement();
            //beans迭代器
            Iterator beansIterator = beans.elementIterator();
            while (beansIterator.hasNext()) {
                Element bean = beansIterator.next();
                String idStr = bean.attributeValue("id");
                String classStr = bean.attributeValue("class");
    
                Class> clazz = Class.forName(classStr);
                Constructor> constructor = clazz.getConstructor();
                //利用获取到的无参构造生成目标对象
                Object object = constructor.newInstance();
                //bean迭代器
                Iterator beanIterator = bean.elementIterator();
                while (beanIterator.hasNext()) {
                    Element property = beanIterator.next();
                    //获取属性
                    String propertyName = property.attributeValue("name");
                    String propertyValue = property.attributeValue("value");
                    Field field = clazz.getDeclaredField(propertyName);
                    //获取方法
                    String methodStr = "set" + propertyName.substring(0, 1).toUpperCase() + propertyName.substring(1);
                    Method method = clazz.getMethod(methodStr, field.getType());
    
                    Object value = propertyValue;
                    //判断属性类型并转换
                    switch (field.getType().getName()) {
                        case "java.lang.Integer":
                            value = Integer.parseInt(propertyValue);
                            break;
                        case "java.lang.Double":
                            value = Double.parseDouble(propertyValue);
                            break;
                    }
                    method.invoke(object, value);
                }
                //装入容器
                iocMap.put(idStr, object);
            }
        } catch (DocumentException e) {
            e.printStackTrace();
        } catch (NoSuchMethodException e) {
            e.printStackTrace();
        } catch (ClassNotFoundException e) {
            e.printStackTrace();
        } catch (InstantiationException e) {
            e.printStackTrace();
        } catch (IllegalAccessException e) {
            e.printStackTrace();
        } catch (InvocationTargetException e) {
            e.printStackTrace();
        } catch (NoSuchFieldException e) {
            e.printStackTrace();
        }
    }
    
    • 重写getBean,根据名字从容器中获取bean
     @Override
     public Object getBean(String s) throws BeansException {
         return iocMap.get(s);
     } 
    
  • 测试 Test
public class Test {
public static void main(String[] args) {
   ApplicationContext context = new MyClassPathXmlApplicationContext("spring.xml");
   Book book = (Book) context.getBean("threeBody");
   System.out.println(book);
 }
}
  • 成果
D:\Java_JDK\JDK8\bin\java.exe ...
Book(id=1, name=《三体》, price=59.9)

Process finished with exit code 0

Spring Ioc底层实现

标签:eth   uppercase   根据   version   底层实现   new   element   declared   book   

原文地址:https://www.cnblogs.com/200ok/p/14773185.html

上一篇:Java集合框架-HashMap

下一篇:go语言数组


评论


亲,登录后才可以留言!