本文概览:介绍了IOC的bean生命周期。

准备

如何去看容器初始化源代码?

在spring源码中查看Bean生命周期执行或者说是查看IOC容器初始化的过程,这就需要从初始化容器入口触发,初始化容器入口有哪些?参考:如下,常用的测试的方式就是

Spring IOC一个实例

1 存储生成的bean实例对象

1. 1 对于BeanFactory

对象存放在singletonObjects中,它是currentMap类型,这个变量存在于:DefaultSingletonBeanRegistry类中

所以, 对于一个具体的BeanFactory都是继承了了DefaultSingletonBeanRegistry,否则就无法存放数据了。DefaultSingletonBeanRegistry通过singletonObjects成员保存bean对象:

DefaultSingletonBeanRegistry继承关系为:

9de7b7b3-eb9c-4d29-a025-e3bc9f42bac5

1.2 对于ApplicationContext

对于一个具体上下文类型的实例对象,都有一个BeanFactory成员(都是DefaultListableBeanFactory类型),用来来存放数据,所以又变成了BeanFactory如何存放bean对象的问题。下面以GenericApplicationContextClassPathXmlApplicationContext为例:

1)对于GenericApplicationContext

它定义了一个DefaultListableBeanFactory类型变量:如下

2)对于ClassPathXmlApplicationContext

它继承了AbstractRefreshableApplicationContext,在这个类型中定义了一个 DefaultListableBeanFactory类型变量,如下:

1.3 BeanFactory Appplication区别

1、存储bean

上下文通过BeanFactory存储对象实例。具体的上下文中对象实例中的BeanFactory成员的类型都是 DefaultListableBeanFactory,因为现在在BeanFactory的继承层次中,只有DefaultListableBeanFactor类型是具体类型了,对于XmlBeanFactory现在已经Deprecated不建议使用

2、初始化bean

因为在上下文中都是使用BeanFactory,所以上下文初始化bean也是通过BeanFactory来实现的。

3BeanFactory只能通过BeanDefinition对象来初始化对象。上下文可以通过访问外部文件,解析文件生成RootBeanDefinition

在使用Spring  IOC容器时,都是使用上下文,因为上下文件可以访问外部资源xml文件或者代码中注解,生成BeanDefinition,并将这些BeanDefinition传给BeanFacotory来创建bean对象。

2 ApplicationContext初始化过程

ApplicationContext也是通过DefalutListableBeanFactory来存储的,所以最终的初始化对象也是通过DefaultListableBeanFactorygetBean来完成的。所以可以通过DefaultListableBeanFactory对象的getBean()来查看IOC Bean的生命周期

1266515

下面是上下文初始化的流程:

以手动方式为例,如下,通过ClassPathXmlApplicationContextrefresh()函数 来来查看初始过程

ClassPathXmlApplicationContext context = new ClassPathXmlApplicationContext(“appplicationContext.xml”);

2. AbstractApplicationContext#refresh( )

1)通过getBeanFactory( )函数获取一个DefaultListableBeanFactory

obtainfreshBeanFactory()函数中调用了抽象接口getBeanFactory()

如下两个类的实现了getBeanFactory( )函数获取一个DefaultListableBeanFactory :

(2) DefaultListableBeanFactory中的preInstantiateSingletons()方法

这个类实现了父类实现了ConfigurableListableBeanFactory中的preInstantiateSingletons()方法,这个函数中又调用了AbStractBeanFactorygetBean方法。这里只是调用并没有获取返回值。解释:

AbStractBeanFactorygetBean方法这个函数就是查询一个bean,如果没有就创建。所以这里只是利用了AbStractBeanFactorygetBean方法中创建一个bean实例的功能。

2AbStractBeanFactorygetBean() 方法

1AbstractBeanFactorydoGetBean)  【体现了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。

版面 3

1. 创建对象实例

包含Bean的生命周期 :

  •    生命周期1:InstantiationAwareBeanPostProcessor#postProcessBeforeInstantiation方法
  •    生命周期2:创建bean对象阶段。

提供了resolveBeforeInstantiation() 和 doCreateBean()两种创建bean的方式。目前来看只有groovy和spring结合时才使用resolveBeforeInstantiation()来创建对象。resolveBeforeInstantiation(beanName, mbd) 和 doCreateBean两种方式只能选一种。

(1)第一种方式

如果这个方法能够创建一个对象,就不进行 InstantiationAwareBeanPostProcessor#postProcessBeforeInstantiation了。目前实行这个方法的类只有ScriptFactoryPostProcessor,其他InstantiationAwareBeanPostProcessor类这个postProcessBeforeInstantiation方法都是返回Null。

(2)第二种方式  doCreateBean(beanName, mbd, args);

包含生命周期:

     生命周期1:创建bean对象阶段

这一步只是创建了对象,还没有对成员进行初始化,常见初始化方式有:在xml中配置的属性(<bean>)和通过注解(@Resource、@Autowire)标注的属性。

通过createBeanInstance(beanName, mbd, args)生成一个BeanWrapper对象,在这个函数中通过 调用构造函数或者工厂方法来生成一个实体。如下三个方法来创建对象:

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 生命周期应用

获取上下文

Spring IOC常用编程模式

分类&标签