Spring注解学习_生命周期2_BeanPostProcessor
**BeanPostProcessor接口:**在bean初始化前后进行一些处理工作
这个接口需要实现两个方法:
- postProcessBeforeInitialization( ):在创建好的Bean实例任何初始化之前调用
- postProcessAfterInitialization( ):在创建好的Bean实例任何初始化之后调用
¶实现BeanPostProcessor
我们自行实现一个后置处理器:
public class MyBeanPostProcessor implements BeanPostProcessor {
//在bean初始化之前调用
@Override
public Object postProcessBeforeInitialization(Object bean, String beanName) throws BeansException {
System.out.println("postProcessBeforeInitialization..."+beanName);
return bean;
}
//在bean初始化之后调用
@Override
public Object postProcessAfterInitialization(Object bean, String beanName) throws BeansException {
System.out.println("postProcessAfterInitialization..."+beanName);
return bean;
}
}
还是用上一篇文章的配置类和测试类:
@Configuration
@Import(MyBeanPostProcessor.class)
public class MainConfig3 {
@Bean(initMethod = "init",destroyMethod = "destroy")
public Car car(){
return new Car();
}
@Bean
public Cat cat(){
return new Cat();
}
@Bean
public Dog dog(){
return new Dog();
}
}
测试,发现对于所有注册的bean都生效了:
¶BeanPostProcessor原理
手动debug发现,Bean的自动装配,在AbstractAutowireCapableBeanFactory类中,经过了如下方法调用:
protected Object createBean(String beanName, RootBeanDefinition mbd, @Nullable Object[] args) throws BeanCreationException {
...
try {
Object beanInstance = doCreateBean(beanName, mbdToUse, args);
if (logger.isTraceEnabled()) {
logger.trace("Finished creating instance of bean '" + beanName + "'");
}
return beanInstance;
}
...
}
...
protected Object doCreateBean(final String beanName, final RootBeanDefinition mbd, final @Nullable Object[] args) throws BeanCreationException {
...
try {
//给bean进行属性复制
populateBean(beanName, mbd, instanceWrapper);
//进行初始化
exposedObject = initializeBean(beanName, exposedObject, mbd);
}
...
}
...
(有个值得注意的点:创建bean时,先调用populateBean给bean属性赋值,再initializeBean调用初始化方法。)
我们看看代码注释中对populateBean(beanName, mbd, instanceWrapper)的定义:
Populate the bean instance in the given BeanWrapper with the property values from the bean definition.(用bean定义中的属性值填充给定BeanWrapper中的bean实例。)
再看看对InitializeBean(final String beanName, final Object bean, @Nullable RootBeanDefinition mbd)的定义:
Initialize the given bean instance, applying factory callbacks as well as init methods and bean post processors.
Called from {@link #createBean} for traditionally defined beans, and from {@link #initializeBean} for existing bean instances.(初始化给定的bean实例,应用工厂回调以及init方法和bean后处理器。
从{@link #createBean}为传统定义的bean调用,从{@link #initializeBean}为现有的bean实例调用。)
然后直接看InitializeBean源码:
调用initializeBean方法:
进入applyBeanPostProcessorsBeforeInitialization方法:
而后置处理器则为我们之前自行实现并注册的MyBeanPostProcessor,里面重写的方法将被用到。
//在bean初始化之前调用
@Override
public Object postProcessBeforeInitialization(Object bean, String beanName) throws BeansException {
System.out.println("postProcessBeforeInitialization..."+beanName);
return bean;
}
故不难得知initializeBean处理流程大致为:
initializeBean{
1️⃣ applyBeanPostProcessorsBeforeInitialization(Object existingBean, String beanName)
2️⃣ invokeInitMethods(beanName, wrappedBean, mbd);
3️⃣ applyBeanPostProcessorsAfterInitialization(wrappedBean, beanName);
}
-
applyBeanPostProcessorsBeforeInitialization会遍历容器中所有的BeanPostProcessor,逐个执行后置处理器中实现的 postProcessBeforeInitialization() 方法,一旦返回null,跳出循环,不会再执行后面的postProcessBeforeInitialization() 方法。
-
然后再执行初始化方法:invokeInitMethods(beanName, wrappedBean, mbd);
-
最后执行applyBeanPostProcessorsAfterInitialization 方法,其过程与1️⃣大体相同。
¶Spring底层对BeanPostProcessor的使用:
bean赋值,注入其他组件,@Autowired,bean声明周期的注解功能,@Async等等,都用到了BeanPostProcessor。可在IDEA中用快捷键Ctrl+Alt+B查看其具体实现类。
¶ApplicationContextAwareProcessor
ApplicationContextAwareProcessor也实现了BeanPostProcessor接口,它的作用是帮我们**向组件(Compenent)中注入IOC容器(ApplicationContext)**依赖。另外,要想通过这种方式在组件中注入IOC容器,我们需先让组件实现ApplicationContextAware接口。这里分析一下原理:
直接看ApplicationContextAwareProcessor的源码:
首先它自己就通过构造注入得到了IOC容器依赖:
/**
* Create a new ApplicationContextAwareProcessor for the given context.
*/
public ApplicationContextAwareProcessor(ConfigurableApplicationContext applicationContext) {
this.applicationContext = applicationContext;
this.embeddedValueResolver = new
EmbeddedValueResolver(applicationContext.getBeanFactory());
}
然后由于实现了BeanPostProcessor接口,在初始化前会调用postProcessBeforeInitialization方法:
查看 InvokeAwareInterfaces() 方法的源码:
¶InitDestroyAnnotationBeanPostProcessor
类似的,InitDestroyAnnotationBeanPostProcessor类也通过实现BeanPostProcessor接口来完成对bean的所有标注的初始化和销毁方法调用。对于标注了@PostConstruct,@PreDestroy等注解的bean:
public class Dog{
//对象创建并赋值之后调用
@PostConstruct
public void init(){
System.out.println("dog @PostConstruct...");
}
//容器销毁对象之前调用
@PreDestroy
public void destroy(){
System.out.println("dog @PreDestroy...");
}
}
先看这个类如何实现postProcessBeforeInitialization(初始化前处理):
调用findLifecycleMetadata(bean.getClass()) 找到生命周期元数据(其中包括我们标注@PostConstruct和@PreDestroy的初始化、销毁方法)找到之后调用invokeInitMethod执行初始化方法↓
对于@PreDestroy标注的销毁方法调用,也是类似的处理思路
我们经常用到的**@Autowired**,它的处理类AutowiredAnnotationBeanPostProcessor也是实现了BeanPostProcessor,以后写@Autowired时再深入分析。
转载请注明来源,欢迎对文章中的引用来源进行考证,欢迎指出任何有错误或不够清晰的表达,邮件至 708801794@qq.com
文章标题:Spring注解学习_生命周期2_BeanPostProcessor
文章字数:1.1k
本文作者:梅罢葛
发布时间:2020-03-30, 01:51:10
最后更新:2020-03-30, 17:37:53
原始链接:https://qiurungeng.github.io/2020/03/30/Spring%E6%B3%A8%E8%A7%A3%E5%AD%A6%E4%B9%A0-%E7%94%9F%E5%91%BD%E5%91%A8%E6%9C%9F2-BeanPostProcessor/