目录
本文概览:介绍了IOC的bean生命周期。
准备
如何去看容器初始化源代码?
在spring源码中查看Bean生命周期执行或者说是查看IOC容器初始化的过程,这就需要从初始化容器入口触发,初始化容器入口有哪些?参考:如下,常用的测试的方式就是
1 |
ClassPathXmlApplicationContext context = new ClassPathXmlApplicationContext(xx.xml); |
1 存储生成的bean实例对象
1. 1 对于BeanFactory
对象存放在singletonObjects中,它是currentMap类型,这个变量存在于:DefaultSingletonBeanRegistry类中
所以, 对于一个具体的BeanFactory都是继承了了DefaultSingletonBeanRegistry,否则就无法存放数据了。DefaultSingletonBeanRegistry通过singletonObjects成员保存bean对象:
1 2 |
/** Cache of singleton objects: bean name --> bean instance */ private final Map<String, Object> singletonObjects = new ConcurrentHashMap<String, Object>(64); |
DefaultSingletonBeanRegistry继承关系为:
1.2 对于ApplicationContext
对于一个具体上下文类型的实例对象,都有一个BeanFactory成员(都是DefaultListableBeanFactory类型),用来来存放数据,所以又变成了BeanFactory如何存放bean对象的问题。下面以GenericApplicationContext和ClassPathXmlApplicationContext为例:
(1)对于GenericApplicationContext
它定义了一个DefaultListableBeanFactory类型变量:如下
1 |
private final DefaultListableBeanFactory beanFactory; |
(2)对于ClassPathXmlApplicationContext
它继承了AbstractRefreshableApplicationContext,在这个类型中定义了一个 DefaultListableBeanFactory类型变量,如下:
1 |
private DefaultListableBeanFactory beanFactory; |
1.3 BeanFactory 与 Appplication区别
1、存储bean
上下文通过BeanFactory存储对象实例。具体的上下文中对象实例中的BeanFactory成员的类型都是 DefaultListableBeanFactory,因为现在在BeanFactory的继承层次中,只有DefaultListableBeanFactor类型是具体类型了,对于XmlBeanFactory现在已经Deprecated不建议使用
2、初始化bean
因为在上下文中都是使用BeanFactory,所以上下文初始化bean也是通过BeanFactory来实现的。
3、BeanFactory只能通过BeanDefinition对象来初始化对象。上下文可以通过访问外部文件,解析文件生成RootBeanDefinition。
在使用Spring IOC容器时,都是使用上下文,因为上下文件可以访问外部资源xml文件或者代码中注解,生成BeanDefinition,并将这些BeanDefinition传给BeanFacotory来创建bean对象。
2 ApplicationContext初始化过程
ApplicationContext也是通过DefalutListableBeanFactory来存储的,所以最终的初始化对象也是通过DefaultListableBeanFactory的getBean来完成的。所以可以通过DefaultListableBeanFactory对象的getBean()来查看IOC Bean的生命周期。
下面是上下文初始化的流程:
以手动方式为例,如下,通过ClassPathXmlApplicationContext的refresh()函数 来来查看初始过程
ClassPathXmlApplicationContext context = new ClassPathXmlApplicationContext(“appplicationContext.xml”);
2. AbstractApplicationContext#refresh( )
(1)通过getBeanFactory( )函数获取一个DefaultListableBeanFactory。
1 |
ConfigurableListableBeanFactory beanFactory = obtainFreshBeanFactory(); |
obtainfreshBeanFactory()函数中调用了抽象接口getBeanFactory()
如下两个类的实现了getBeanFactory( )函数获取一个DefaultListableBeanFactory :
1 2 |
GenericApplicationContext#getBeanFactory( ) AbstractRefreshableApplicationContext#getBeanFactory( ) |
(2) DefaultListableBeanFactory中的preInstantiateSingletons()方法
这个类实现了父类实现了ConfigurableListableBeanFactory中的preInstantiateSingletons()方法,这个函数中又调用了AbStractBeanFactory中getBean方法。这里只是调用并没有获取返回值。解释:
AbStractBeanFactory中getBean方法这个函数就是查询一个bean,如果没有就创建。所以这里只是利用了AbStractBeanFactory中getBean方法中创建一个bean实例的功能。
2、AbStractBeanFactory中getBean() 方法
(1)AbstractBeanFactory的doGetBean() 【体现了Bean完整的生命周期:用来创建对象和初始化对象成员】
2 Bean生命周期
Bean生命周期:用来创建Bean对象、初始化对象成员和销毁对象。
2.1 创建和初始化对象
创建对象包括:
- xml配置<bean>
- 注解@Service、@Controller、@Repository
初始化成员包括:
- xml的方式。<property>和<autowire>;init-method和destroy-method指定的方法。
- 注解方式。如@Resource和@Autowire;
- Bean级生命周期接口方法。 这个包括了BeanNameAware、BeanFactoryAware、ApplicationContextAware、InitializingBean、DiposableBean这些接口的方法。
- 容器级生命周期接口方法-后置处理器 。这个包括了InstantiationAwareBeanPostProcessor 和 BeanPostProcessor 这两个接口实现。如我们可以自定义一个BeanPostcessor,在IOC初始化时,就会注册这个BeanPostProcessor。
1. 创建对象实例
包含Bean的生命周期 :
- 生命周期1:InstantiationAwareBeanPostProcessor#postProcessBeforeInstantiation方法
- 生命周期2:创建bean对象阶段。
提供了resolveBeforeInstantiation() 和 doCreateBean()两种创建bean的方式。目前来看只有groovy和spring结合时才使用resolveBeforeInstantiation()来创建对象。resolveBeforeInstantiation(beanName, mbd) 和 doCreateBean两种方式只能选一种。
(1)第一种方式
1 |
Object bean = resolveBeforeInstantiation(beanName, mbd) |
如果这个方法能够创建一个对象,就不进行 InstantiationAwareBeanPostProcessor#postProcessBeforeInstantiation了。目前实行这个方法的类只有ScriptFactoryPostProcessor,其他InstantiationAwareBeanPostProcessor类这个postProcessBeforeInstantiation方法都是返回Null。
(2)第二种方式 doCreateBean(beanName, mbd, args);
包含生命周期:
生命周期1:创建bean对象阶段
这一步只是创建了对象,还没有对成员进行初始化,常见初始化方式有:在xml中配置的属性(<bean>)和通过注解(@Resource、@Autowire)标注的属性。
通过createBeanInstance(beanName, mbd, args)生成一个BeanWrapper对象,在这个函数中通过 调用构造函数或者工厂方法来生成一个实体。如下三个方法来创建对象:
1 2 3 4 5 6 7 8 |
(1)instantiateUsingFactoryMethod() ConstructorResolver#instantiateUsingFactoryMethod (2)autowireConstructor() ;执行有参数的构造函数 通过ConstructorResolver#autowireConstructor()函数 (3)instantiateBean(); 执行默认构造函数。通过自动检测来创建对象实例时,都是通过执行该默认构造函数来创建对象。 通过CglibSubclassingInstantiationStrategy#instantiate完成。 |
2、填充属性
通过populateBean(beanName, mbd, instanceWrapper) 填充属性,包括两种配置属性: 注解配置和xml配置(如<property>和<autowire>),包含的生命周期有:
- InstantiationAwareBeanPostProcessor#postProcessAfterInstantiation,检验是否还需要进行装配属性,如果可以的话,就不执行下面的两个生命周期了
- InstantiationAwareBeanPostProcessor#postProcessPropertyValues,初始化注解成员
- 通过xml的配置来初始化.即非自动检测方法初始化bean。
poputlateBean函数的执行步骤:
第一步 :获取xml属性值。如xml的<property>和<autowire>
- <property>:PropertyValues pvs = mbd.getPropertyValues();
- <autowire>:通过autowireByName()和autowireByType()方法来获取所有xml配置的自动检测的属性的值,保存到MutablePropertyValues类型变量中
第二步 :通过InstantiationAwareBeanPostProcessor#postProcessPropertyValues()用来为注解初始化成员变 量。(此处用了CommonAnnotationBeanPostProcessor类)
- 在CommonAnnotationBeanPostProcessor#postProcessPropertyValues()处理@Resource等Javax.annotation的注解,包含三个注解@Resource,@WebServiceRef,@EJB
- AutowireAnnotationBeanPostprocessor#postProcessPropertyValues()处理两个注解:@Autowired和@value
- 在RequireAnnotaitonBeanPostProcessor#postProcessPropertyValues(),包含一个注解:@Required
第三步:applyPropertyValues(beanName, mbd, bw, pvs) 使用 xml中配置的属性值来为对象赋值。
3、初始化成员
通过 initializeBean(beanName, exposedObject, mbd)来实现,涉及到生命周期有:
- 对应Bean生命周期中BeanNameAware接口, BeanFactoryAware接口,
- BeanPostProcessor#postProcessBeforeInitialization,如ApplicationContextAware接口
- InitializingBean接口
- xml中<init-method>
- BeanPostProcessor#postProcessAfterInitialization
2.2 销毁对象
包含生命周期有:
- 调用DisposableBean的afterPropertiesSet方法。
- 调用destroy-method属性配置的销毁方法。
3 生命周期应用
获取上下文