Bean的生命周期:创建 -> 初始化 -> 销毁 的过程。Bean的生命周期由Spring 容器管理 。我们可以自定义Bean的初始化和销毁方法,容器在Bean进行到当前生命周期的时候来调用我们自定义的初始化和销毁方法。
Bean创建:Bean创建的时候,单实例Bean是在容器启动的时候创建,多实例Bean是在每次获取的时候创建对象。
Bean初始化:对象创建完成,并赋值好后,调用初始化方法。
Bean销毁:单实例Bean是在Spring容器关闭的时候调用销毁的方法。多实例Bean,Spring容器是不会调用销毁方法。我们可以手动调用销毁方法。
由五种定义初始化和销毁方法的方式:
方式一:在使用xml配置方式的时候,我们可以在
<bean>
标签中指定init-method
和destroy-method
两个属性来指定初始化和销毁方法,初始化和销毁方法不能有参数,但可以抛出异常。方式二:使用
@Bean
指定初始化和销毁方法。方式三:让Bean实现
InitializingBean
和DisposableBean
接口方式四:使用JSR250规范里的
@PostConstruct
和@PreDestroy
注解。方式五:使用Bean的后置处理器
BeanPostProcessor
。后置处理器的作用:在Bean初始化前后进行一些处理操作。
1 @Bean指定初始化和销毁方法
@Bean
注解由两个属性:initMethod
和destroyMethod
。通过这两个方法来指定初始化和销毁方法。
一、有一个Bean如下:
1 | public class Car { |
二、配置类如下,在配置类中我们注入了Car这个Bean,并使用@Bean
注解指定了这个Bean的初始化和销毁方法。
1 |
|
2 Bean实现InitializingBean和DisposableBean接口
让Bean实现InitializingBean
接口,并重写初始化方法afterPropertiesSet
。该方法会在Bean创建完成,并属性都赋值完成后调用。
让Bean实现DisposableBean
接口,并重写销毁方法destroy
。单实例Bean,该方法在容器关闭的时候调用。
示例:
1 |
|
配置类中使用包扫描注入该Bean。
3 使用@PostConstruct和@PreDestroy注解
@PostConstruct
:在Bean创建完成,并且属性赋值完成后,来执行初始化方法。
@PreDestroy
:在容器销毁Bean之前,来执行销毁方法。
注意:@PostConstruct
和@PreDestroy
都是只能标注在方法上的注解。
示例:
1 |
|
配置类中使用包扫描注入该Bean。
4、使用后置处理器BeanPostProcessor
4.1 BeanPostProcessor的示例
后置处理器BeanPostProcessor
是一个接口,它有两个方法:postProcessBeforeInitialization
和postProcessAfterInitialization
。
postProcessBeforeInitialization
:在创建Bean实例,对Bean的属性赋值,并在任何初始化方法调用之前执行,例如实现InitializingBean
接口的afterPropertiesSet
方法,或者是自定义的init-method
方法。1
2> 原文:Apply this BeanPostProcessor to the given new bean instance <i>before</i> any bean initialization callbacks (like InitializingBean's {@code afterPropertiesSet} or a custom init-method).
>postProcessAfterInitialization
:在初始化方法调用之后执行。1
2> 原文:Apply this BeanPostProcessor to the given new bean instance <i>after</i> any bean initialization callbacks (like InitializingBean's {@code afterPropertiesSet} or a custom init-method).
>
一、定义自己的后置处理器
1 |
|
执行顺序:构造方法 -> 后置处理器的前置处理 -> afterPropertiesSet/@PostConstruct -> 后置处理器的后置处理。
简而言之,在 初始化方法执行之前执行
postProcessBeforeInitialization
,在初始化方法执行之后执行postProcessAfterInitialization
。若没有自定义初始化方法,后置处理器也是会执行的。
4.2 BeanPostProcessor的原理
通过查看Spring源码,AbstractAutowireCapableBeanFactory
类中有一个initializeBean
方法,该方法中调用了invokeInitMethods
方法,用来执行初始化方法(afterPropertiesSet
或自定义初始化方法)。在调用了invokeInitMethods
方法前调用了applyBeanPostProcessorsBeforeInitialization
方法,在调用了invokeInitMethods
方法后调用了applyBeanPostProcessorsAfterInitialization
方法。
源码:
1 | protected Object initializeBean(final String beanName, final Object bean, RootBeanDefinition mbd) { |
在执行
initializeBean
之前执行了populateBean
方法,对bean属性进行赋值。
4.3 BeanPostProcessor在Spring底层的使用
以几个BeanPostProcessor
的实现类为例:
4.3.1 ApplicationContextAwareProcessor
一、【作用】:是可以向组件中注入IOC容器。
二、【使用】:
例如有一个组件Pig
,实现ApplicationContextAware
接口,重写接口中的setApplicationContext
方法。
1 | public class Pig implements ApplicationContextAware { |
这样就把容器注入到组件中了。
三、【原理】:
通过查看ApplicationContextAwareProcessor
中的postProcessBeforeInitialization
方法:
1 | class ApplicationContextAwareProcessor implements BeanPostProcessor { |
以我们这个为例,在bean执行初始化之前,先判断这个bean是否实现了
ApplicationContextAware
,如果是,则调用invokeAwareInterfaces
,向bean中注入值。如果是
ApplicationContextAware
,就将applicationContext
注入。
4.3.2 InitDestroyAnnotationBeanPostProcessor
一、【作用】:用来处理@PostConstruct
和@PreDestroy
注解的。这就是为什么标注了这两个注解的方法称为生命周期方法的原因。
二、【原理】:
1 | public class InitDestroyAnnotationBeanPostProcessor |
4.3.3 AutowiredAnnotationBeanPostProcessor
【作用】:用来处理@Autowired
注解,这就是为什么标注的@AutoWired
注解的属性可以进行依赖注入的原因。