三连支持 一起鼓励 一起进步
Bean生命周期
文章目录
- 一、生命周期
- 1.@Bean中配置生命周期
- 2.实现InitializingBean和DisposableBean接口
- 3.@PostConstruct & @PreDestroy
- 4.BeanPostProcessor接口
- 二、执行过程
- 三、源码中使用的BeanPostProcessor
- 1.以ApplicationContextAwareProcesser为例。
- 2.在Bean中使用示例:
一、生命周期
Bean的生命周期:
容器管理bean的生命周期。
1.@Bean中配置生命周期
使用@Bean注解的initMethod、destroyMethod两个属性配置bean的初始化和销毁方法。
public class Car {
public Car() { System.out.println("Car constructor..."); }
public void init() { System.out.println("car .... init ..."); }
public void destroy() { System.out.println("car...destroy"); }
}
配置@Bean注解
@Configuration
public class MainConfigOfLifeCycle {
@Bean(initMethod = "init", destroyMethod = "destroy")
public Car car() {
return new Car();
}
}
2.实现InitializingBean和DisposableBean接口
InitializingBean接口的afterPropertiesSet()实现初始化逻辑;
DispoableBean接口的destroy()实现销毁逻辑;
public class Car implements InitializingBean, DisposableBean {
public Car() {
System.out.println("Car constructor...");
}
public void init() {
System.out.println("car .... init ...");
}
@Override
public void destroy() {
System.out.println("car...destroy");
}
@Override
public void afterPropertiesSet() throws Exception {
init();
}
}
3.@PostConstruct & @PreDestroy
JSR250注解:
● @PostConstrct,标注在方法上,对象执行构造行数,创建并赋值之后执行
● @PreDestroy,标注在方法上,在容器移除对象之前执行
public class Car{
public Car() {
System.out.println("Car constructor...");
}
@PostConstruct
public void init() {
System.out.println("car .... init ...");
}
@PreDestroy
public void destroy() {
System.out.println("car...destroy");
}
}
4.BeanPostProcessor接口
Bean的后置处理器,在bean的初始化前后进行处理。
● postProcessBeforeInitialization
Bean构造方法执行之后、初始化方法执行之前 处理
● postProcessAfterInitialization
Bean初始化之后处理
自定义BeanPostProcessor
@Component
public class MyBeanPostProcessor implements BeanPostProcessor {
@Override
public Object postProcessBeforeInitialization(Object bean, String beanName) throws BeansException {
System.out.println("before init..." + beanName);
return bean; // 返回传入的原始bean,或者进行了包装之后的bean
}
@Override
public Object postProcessAfterInitialization(Object bean, String beanName) throws BeansException {
System.out.println("after init ..." + beanName);
return bean;// 返回传入的原始bean,或者进行了包装之后的bean
}
}
二、执行过程
AbstractAutowireCapableBeanFactory.doCreateBean中调用popolulateBean为bean填充属性,然后调用initializeBean开始进行bean的初始化以及bean初始化的前后处理。
AbstractAutowireCapableBeanFactory.doCreateBean调用initializeBean方法:
该方法会先调用applyBeanPostProcessorsBeforeInitialization(warppedBean, beanName);初始化前前置处理
然后调用invokeInitMethods对bean进行初始化
最后调用applyBeanPostProcessorsAfterInitialization,初始化后置处理。
如图:
applyBeanPostProcessorsBeforeInitialization会遍历所有的BeanPostProcessor,执行每个BeanPostProcessor的postProcessBeforeInitialization方法,如果某个BeanPostProcessor::postProcessBeforeInitialization返回null,则直接退出循环,不再执行后面的BeanPostProcessor。
三、源码中使用的BeanPostProcessor
源码中有很多组件通过BeanPostProcessor进行实现。
1.以ApplicationContextAwareProcesser为例。
ApplicationContextAWareProcesser可以为Bean中注入ioc容器。利用的就是BeanPostProcessor的postProcessBeforeInitialization方法:获取bean实现的接口,然后根据实现的接口不同,调用相应的方法,把ioc容器传入对应的方法参数内。
public Object postProcessBeforeInitialization(final Object bean, String beanName) throws BeansException {
AccessControlContext acc = null;
if (System.getSecurityManager() != null &&
(bean instanceof EnvironmentAware || bean instanceof EmbeddedValueResolverAware ||
bean instanceof ResourceLoaderAware || bean instanceof ApplicationEventPublisherAware ||
bean instanceof MessageSourceAware || bean instanceof ApplicationContextAware)) {
acc = this.applicationContext.getBeanFactory().getAccessControlContext();
}
// ....
invokeAwareInterfaces(bean);
return bean;
}
private void invokeAwareInterfaces(Object bean) {
if (bean instanceof Aware) {
if (bean instanceof EnvironmentAware) {
((EnvironmentAware) bean).setEnvironment(this.applicationContext.getEnvironment());
}
if (bean instanceof EmbeddedValueResolverAware) {
((EmbeddedValueResolverAware) bean).setEmbeddedValueResolver(this.embeddedValueResolver);
}
if (bean instanceof ResourceLoaderAware) {
((ResourceLoaderAware) bean).setResourceLoader(this.applicationContext);
}
if (bean instanceof ApplicationEventPublisherAware) {
((ApplicationEventPublisherAware) bean).setApplicationEventPublisher(this.applicationContext);
}
if (bean instanceof MessageSourceAware) {
((MessageSourceAware) bean).setMessageSource(this.applicationContext);
}
if (bean instanceof ApplicationContextAware) {
((ApplicationContextAware) bean).setApplicationContext(this.applicationContext);
}
}
}
2.在Bean中使用示例:
Car类实现ApplicationContextWareProcesser中判断的可以注入ioc容器的接口,然后实现对应的方法
public class Car implements ApplicationContextAware {
private ApplicationContext applicationContext;
public Car() {
System.out.println("Car constructor...");
}
@Override
public void setApplicationContext(ApplicationContext applicationContext) throws BeansException {
System.out.println("为car注入applicationContext");
this.applicationContext = applicationContext;
}
}