Spring解析

来源:互联网 发布:淘宝双十一打几折 编辑:程序博客网 时间:2024/06/03 17:06

Spring: IOC容器、AOP

一、 IOC容器

1. xmlBeanDefinitionReader.loadBeanDefinition(url : String)读取Xml文件xmlBeanDefinitionReader的构造需要传入一个Resource对象xmlBeanDefinitionReader内部就是一个map结构,<name, BeanDefinition>

2. 注册到BeanFactory,BeanFactory内部也是一个map结构

3. 从BeanFactory中根据key获取value,即获取已加载的类

(1)BeanDefinition:包装Bean的实体类,包括包装类的类名、类的Class对象和类属性。在读取xml文件解析xml的各个节点时,获取class节点的值,即获取class,通过解析xml文件构造BeanDefinition对象,在设置beanClassName的时候就根据className调用Class.forName(className)加载类,此时类的对象已经构造完成

(2)Bean的属性注入:我们将属性注入信息包装成PropertyValue对象,并且保存在BeanDefinition对象中。这样是初始化bean时就可以根据PropertyValue来进行属性注入。Spring本身使用的setter注入

(3)处理Bean之间的依赖:定义一个BeanReference类,用表示这个属性对另一个Bean的引用。这个在解析xml文件的时候进行初始化,并在初始化bean的时候进行解析和真实的bean注入。为了解决循环依赖的问题,我们采用lazy-init的方式,将createBean的事情放在getBean的时候去执行。如果该属性对应的bean找不到,那就先创建它。因为总是先创建再注入,所以就不存在两个bean循环创建而导致的死锁问题。这其中对属性的获取就是采用反射机制

for (PropertyValue propertyValue : mbd.getPropertyValues().getPropertyValues()) {    Field declaredField = bean.getClass().getDeclaredField(propertyValue.getName());    declaredField.setAccessible(true);    Object value = propertyValue.getValue();    if (value instanceof BeanReference) {        BeanReference beanReference = (BeanReference) value;        value = getBean(beanReference.getName());    }    declaredField.set(bean, value);}

(4)ApplicationContext:applicationContext.getBean(className)其内部调用的就是beanFactory.getBean(className)。ApplicationContext通过ClassPathXmlApplicationContext加载xml文件,内部对xml的解析也是调用XMLBeanDefinitionReader。引入ClassPathXmlApplicationContext接口,对用户来说是简化的操作,只需使用ClassPathXmlApplicationContext传入xml文件的url构造ApplicationContext对象,在使用applicationContext对象调用getBean方法就可以获取bean对象,内部的操作都封装在getBean中。

ApplicationContext applicationContext = new ClassPathXmlApplicationContext("tinyioc.xml");HelloWorldService helloWorldService = (HelloWorldService) applicationContext.getBean("helloWorldService");helloWorldService.helloWorld();