Bean的生命周期

时间:2021-06-29 19:05:41

为了更好的了解自定义属性编辑器,我们现在先了解Bean的生命周期。
Spring中,ApplicationContext对bean的管理,是在其封装的BeanFactory实例的基础上,提供了一些其他对bean的操作,下面以ApplicationContext中bean的生命周期来说明

 

 

[ 启动容器 ]

1 调用BeanFactoryPostProcessor工厂后处理器的postProcessBeanFactory()对BeanDefinition对象进行后处理

这是ApplicationContext启动时,refresh方法中执行的,加工处理BeanDefinition(spring提供了一个CustomEditorConfigurer实现了BeanFactoryPostProcessor,用来实现对自定义属性编辑器的注册。之所以通过它来实现注册是因为工厂后处理器可以访问到beanFactory容器,从而获取用户自定义的BeanDefinition从而实例化并注册)

[ 通过调用getBean()获取某个bean(ApplicationContext或者BeanFactory)]

2 调用InstantiationAwareBeanPostProcessor的postProcessBeforeInstantiation()方法

如果容器注册了InstantiationAwareBeanPostProcessor接口,在实例化bean之前,将调用接口的postProcessBeforeInstantiation()

3 实例化

根据配置情况调用Bean的构造函数或工厂方法实例化Bean

4 调用InstantiationAwareBeanPostProcessor的postProcessAfterInstantiation()方法

如果容器注册了InstantiationAwareBeanPostProcessor接口,在实例化bean之后,将调用接口的postProcessAfterInstantiation()

5 调用InstantiationAwareBeanPostProcessor的postProcessPropertyValues()方法

如果<bean>配置了<property>属性,容器在第六步着手将配置值设置到bean对应的属性当中,不过在设置每个属性之前将先调用InstantiationAwareBeanPostProcessor的postProcessPropertyValues()方法

6 设置属性值

调用bean的属性设置方法设置属性

7 调用BeanNameAware的setBeanName()方法

如果bean实现了org.springframework.beans.factory.BeanNameAware接口,将调用setBeanName()接口方法,将配置文件中该bean对应的名称设置到bean中

8 调用BeanFactoryAware的setBeanFactory()方法

如果bean实现了org.springframework.beans.factory.BeanFactoryAware接口,将调用setBeanFactory()接口方法,将beanFactory容器设置到bean中

9 调用ApplicationContextAware的setApplicationContext()方法

如果bean实现了org.springframework.context.ApplicationContextAware接口,会调用该接口setApplicationContext方法

10 调用BeanPostProcessor的postProcessBeforeInitialization()方法

(容器初始化时注册,在此调用/ 而若只应用BeanFactory,则要在客户应用代码中手动注册)

如果BeanFactory装配了org.springframework.beans.factory.config.BeanPostProcessor后处理器,将会调用BeanPostProcessor的Object postProcessBeforeInitialization(Object bean,String beanName)接口方法对bean进行加工操作。入参bean是当前处理的bean,而beanName则是当前bean的配置名,返回的对象为加工处理后的bean。用户可以使用该方法对bean进行特殊处理,甚至改变bean的行为。它为容器提供了bean进行后续加工的切入点,Spring容器所提供的各种功能(如AOP,动态代理等)都通过BeanPostProcessor实施。

11 调用InitializingBean的afterPropertiesSet()方法

如果bean实现了InitializingBean接口,将调用该接口的afterPropertiesSet()。

12 调用通过init-method属性配置的初始化方法

如果bean通过配置文件中init-method属性定义了初始化方法,会执行这个方法。

13 调用BeanPostProcessor的postProcessAfterInitialization()方法

 

如果在bean配置中指定bean的作用范围scope="prototype",会将bean返回给调用者,调用者负责bean后续生命周期的管理,spring不再管理这些bean的生命周期。如果作用范围为scope="singleton",则将bean放入Spring的Ioc容器的缓存池中,并将bean引用返回给调用者,Spring继续对这些bean进行后续的生命周期管理

     (singleton)Spring缓存中准备就绪的bean

     (prototype)准备就绪的bean

[ 容器销毁 ]

14 调用DisposableBean的afterPropertiesSet()方法

对于scope="singleton"的bean,当容器关闭时,将触发Spring对bean的后续生命周期的管理工作。首先如果bean实现了DisposableBean接口,则将调用接口的afterPropertiesSet()方法,可以在此编写资源释放,记录日志等操作

15 调用destroy-method属性配置的销毁方法

对于scope="singleton"的bean,当容器关闭时,如果bean的destroy-method属性指定了bean的销毁方法,spring将执行这个方法,完成bean资源的释放等操作

 

Bean自身的方法:调用构造函数实例化bean,调用setter设置属性,调用init-method,destroy-method

Bean级生命周期接口方法:如BeanNameAware,BeanFactoryAware,InitializingBean和DisposableBean,这些接口由bean直接实现

容器级生命周期接口方法:有InstantiationAwareBeanPostProcessor和BeanPostProcessor这两个接口实现,一般称他们的实现类为后处理器。实现类独立于bean,以容器附加装置的形式注册到spring当中。当spring创建任何bean时,这些后处理器都会发生作用,所以后处理器的影响是全局性的。当然,用户可以通过合理的编写后处理器,让其仅对感兴趣的bean进行加工处理。

 

Bean级生命接口和容器级生命接口是个性和共性辩证统一思想的体现。前者解决bean的个性化处理的问题,后者解决容器中某些bean共性化处理的问题

Spring容器中可以注册多个后处理器,只要他们实现org.springframework.core.Ordered接口,容器将按特定的顺序依次调用这些后处理器

InstantiationAwareBeanPostProcessor其实是BeanPostProcessor的子接口,在spring 1.2中定义,在spring2.0中为其提供了一个适配器类InstantiationAwareBeanPostProcessorAdapter。

 

到目前为止,我们已经知道Bean在Spring上下文的生命周期。