浅谈Spring中几个PostProcessor的区别与联系

网友投稿 784 2022-12-19

浅谈Spring中几个PostProcessor的区别与联系

浅谈Spring中几个PostProcessor的区别与联系

目录Spring几个PostProcessor的区别首先明确 Bean 的生命周期:查看 IOC 容器创建时的调用流程spring-postProcessor的执行时机BeanPostProcessor:postProcessAfterInitialization调用时机:InstantiationAwareBeanPostProcessor总结: 执行顺序

Spring几个PostProcessor的区别

首先明确 Bean 的生命周期:

首先注册 Bean 的定义信息;

然后创建 Bean 的实例;

最后初始化 Bean ,放入容器中。

按照执行的顺序,可以分为以下几个步骤:

BeanDefinitionRegistryPostProcessor 是在注册 Bean 定义信息前后调用;

BeanFactoryPostProcessor 是在创建 Bean 前后调用;

BeanPostProcessor 是在初始化 Bean 前后调用;

其中 BeanDefinitionRegistryPostProcessor 是 BeanFactoryPostProcessor 的子类,所以可以使用前者代替后者实现功能。

查看 IOC 容器创建时的调用流程

refresh 方法代码如下:

// Allows post-processing of the bean factory in context subclasses.

postProcessBeanFactory(beanFactory);

// Invoke factory processors registered as beans in the context.

invokeBeanFactoryPostProcessors(beanFactory);

// Register bean processors that intercept bean creation.

registerBeanPostProcessors(beanFactory);

// Initialize message source for this context.

initMessageSourUvdQxnzwce();

// Initialize event multicaster for this context.

initApplicationEventMulticaster();

// Initialize other special beans in specific context subclasses.

onRefresh();

// Check for listener beans and register them.

registerListeners();

// Instantiate all remaining (non-lazy-init) singletons.

finishBeanFactoryInitialization(beanFactory);

// Last step: publish corresponding event.

finishRefresh();

其中的 invokeBeanFactoryPostProcessors 就执行了注册定义信息和创建 Bean 的方法;而 finishBeanFactoryInitialization 执行了初始化 Bean 的方法。

具体的执行顺序大家可以自行打断点调试,由于涉及的源码过多,这里不再展示。

spring-postProcessor的执行时机

spring bean 的生命周期粗糙的分为以下步骤。

实例化(创建一个属性都为空的对象)---------》属性填充(populateBean,下文中这个步骤我都称为初始化)-----------》init方法的执行(invokerInitMethods,下文称为init)

postprocessor的方法就是穿插在这三个大的步骤中。

BeanPostProcessor:

postProcessBeforeInitialization调用时机

向上找调用者:

继续向上:

看以看出populateBean(初始化bean)-------------------》beanpostBeforeInitialization---------------------------------->invokeinitMethods(配置的init-method)

postProcessAfterInitialization调用时机:

向上:

可以看出在init-method方法之后

看以看出populateBean(初始化bean)-------------------》beanpostBeforeInitialization---------------------------------->invokeinitMethods(配置的init-method)------->postProcessAfterInitialization

public class MBeanPostProcessor implements BeanPostProcessor {

@Override

//populateBean之后 invokeinitMethods之前

public Object postProcessBeforeInitialization(Object bean, String beanName) throws BeansException {

System.out.println("post bean before! :"+beanName);

return bean;

}

@Override

//invokeinitMethods之后

public Object postProcessAfterInitialization(Object bean, String beanName) throws BeansException {

System.out.println("post bean after!"+beanName);

return bean;

}

}

另一个重要的是:

InstantiationAwareBeanPostProcessor

postProcessBeforeInstantiation调用时机:

向上找调用者:

继续向上:

可以看出是在实例化之前:(也就是反射创建对象之前,如果postProcessBeforeInstantiation创建了一个非空的对象,则不会走实例化步骤。)

postProcessAfterInstantiation调用时机:

protected void populateBean(String beanName, RootBeanDefinition mbd, @Nullable BeanWrapper bw) {

PropertyValues pvs = mbd.getPropertyValues();

if (bw == null) {

if (!pvs.isEmpty()) {

throw new BeanCreationException(

mbd.getResourceDescription(), beanName, "Cannot apply property values to null instance");

}

else {

// Skip property population phase for null instance.

return;

}

}

// Give any InstantiationAwareBeanPostProcessors the opportunity to modify the

// state of the bean before properties are set. This can be used, for example,

// to support styles of field injection.

boolean continueWithPropertyPopulation = true;

if (!mbd.isSynthetic() && hasInstantiationAwareBeanPostProcessors()) {

for (BeanPostProcessor bp : getBeanPostProcessors()) {

if (bp instanceof InstantiationAwareBeanPostProcessor) {

InstantiationAwareBeanPostProcessor ibp = (InstantiationAwareBeanPostProcessor) bp;

//在这里执行

if (!ibp.postProcessAfterInstantiation(bw.getWrappedInstance(), beanName)) {

continueWithPropertyPopulation = false;

break;

}

}

}

}

if (!continueWithPropertyPopulation) {

return;

}

省略。。。。。

applyPropertyValues(beanName, mbd, bw, pvs);

}

可以看出是在在初始化之前,具体是属性填充之前。(初始化之前,实例化之后) 如果返回fales,则不会继续初始化,即不会属性填充。

postProcessPropertyValues调用时机:

protected void populateBean(String beanName, RootBeanDefinition mbd, @Nullable BeanWrapper bw) {

PropertyValues pvs = mbd.getPropertyValues();

if (bw == null) {

if (!pvs.isEmpty()) {

throw new BeanCreationException(

mbd.getResourceDescription(), beanName, "Cannot apply property values to null instance");

}

else {

// Skip property population phase for null instance.

return;

}

}

// Give any InstantiationAwareBeanPostProcessors the opportunity to modify the

// state of the bean before properties are set. This can be used, for example,

// to support styles of field injection.

boolean continueWithPropertyPopulation = true;

if (!mbd.isSynthetic() && hasInstantiationAwareBeanPostProcessors()) {

for (BeanPostProcessor bp : getBeanPostProcessors()) {

if (bp instanceof InstantiationAwareBeanPostProcessor) {

InstantiationAwareBeanPostProcessor ibp = (InstantiationAwareBeanPostProcessor) bp;

if (!ibp.postProcessAfterInstantiation(bw.getWrappedInstance(), beanName)) {

continueWithPropertyPopulation = false;

break;

}

}

}

}

if (!continueWithPropertyPopulation) {

return;

}

if (mbd.getResolvedAutowireMode() == RootBeanDefinition.AUTOWIRE_BY_NAME ||

mbd.getResolvedAutowireMode() == RootBeanDefinition.AUTOWIRE_BY_TYPE) {

MutablePropertyValues newPvs = new MutablePropertyValues(pvs);

// Add property values based on autowire by name if applicable.

if (mbd.getResolvedAutowireMode() == RootBeanDefinition.AUTOWIRE_BY_NAME) {

autowireByName(beanName, mbd, bw, newPvs);

}

// Add property values based on autowire by type if applicable.

if (mbd.getResolvedAutowireMode() == RootBeanDefinition.AUTOWIRE_BY_TYPE) {

autowireByType(beanName, mbd, bw, newPvs);

}

pvs = newPvs;

}

boolean hasInstAwareBpps = hasInstantiationAwareBeanPostProcessors();

boolean needsDepCheck = (mbd.getDependencyCheck() != RootBeanDefinition.DEPENDENCY_CHECK_NONE);

if (hasInstAwareBpps || needsDepCheck) {

PropertyDescriptor[] filteredPds = filterPropertyDescriptorsForDependencyCheck(bw, mbd.allowCaching);

if (hasInstAwareBpps) {

for (BeanPostProcessor bp : getBeanPostProcessors()) {

if (bp instanceof InstantiationAwareBeanPostProcessor) {

InstantiationAwareBeanPostProcessor ibp = (InstantiationAwareBeanPostProcessor) bp;

pvs = ibp.postProcessPropertyValues(pvs, filteredPds, bw.getWrappedInstance(), beanName);

if (pvs == null) {

return;

}

}

}

}

if (needsDepCheck) {

checkDependencies(beanName, mbd, filteredPds, pvs);

}

}

applyPropertyValues(beanName, mbd, bw, pvs);

}

在postProcessAfterInstantiation之后,applyPropertyValues之前。(属性填充之前修改属性值)

总结: 执行顺序

1.postProcessBeforeInstantiation(实现这个方法可以做自定义实例化)

2.实例化

3.postProcessAfterInstantiation(是否要初始化)

4.postProcessPropertyValues(修改属性)

5.初始化(属性填充)(populateBean)

6.postProcesstBeforeInitialization( 自定义init方法执UvdQxnzw行之前)

7.invokeinitMethods(执行自定义的init方法)

8.postProcessAfterInitialization(自定义init方法执行之后)

如果加上aware

1.postProcessBeforeInstantiation(实现这个方法可以做自定义实例化)

2.实例化

3.postProcessAfterInstantiation(是否要初始化)

4.postProcessPropertyValues(修改属性)

5.初始化(属性填充)(populateBean)

6.postProcesstBeforeInitialization( 自定义init方法执行之前)

7.invokeAwareMethod

8.invokeinitMethods(执行自定义的init方法)

9.postProcessAfterInitialization(自定义init方法执行之后)

版权声明:本文内容由网络用户投稿,版权归原作者所有,本站不拥有其著作权,亦不承担相应法律责任。如果您发现本站中有涉嫌抄袭或描述失实的内容,请联系我们jiasou666@gmail.com 处理,核实后本网站将在24小时内删除侵权内容。

上一篇:Spring 中如何根据环境切换配置 @Profile
下一篇:MyBatis批量插入的三种方式比较总结
相关文章

 发表评论

暂时没有评论,来抢沙发吧~