BeanPostProcessor注册与Bean生命周期过程

微信公众号原文链接:https://mp.weixin.qq.com/s/QUsaYbwDVQhMIFfy9DFeDAhttps://mp.weixin.qq.com/s/QUsaYbwDVQhMIFfy9DFeDA

疑问

后置处理器有什么作用?
BeanPostProcessor是什么时候被加载到Spring容器中的?
BeanPostProcessor保存在什么地方?
什么时候调用BeanPostProcessor的postProcessBeforeInitialization方法?
什么时候调用BeanPostProcessor的postProcessAfterInitialization方法?
本文将带着上述5个问题对Spring的后置处理器进行揭秘

SpringBoot启动流程简述

SpringBoot在启动过程中,首先会对创建Spring应用上下文ApplicationContext,并为其准备环境变量Environment,然后会扫描包下面的所有bean,并对bean进行解析验证,验证通过后会将bean加载到Spring容器中,加载完成后会对所有的bean进行初始化(即完成bean的生命周期),在进行其生命周期的过程中就会调用BeanPostProcessor相关的方法,对bean进行包装,如设置bean的属性值等;在初始化bean之前,就会将对应的后置处理器加载到Spring容器中。

SpringBoot注册BeanPostProcessor

在Spring组件开发过程中经常会使用到BeanPostProcessor接口,一个类实现了BeanPostProcessor接口,这个类就是一个后置处理器,而后置处理器的作用就是可以对bean进行代理及包装。下面将介绍BeanPostProcessor的注册过程
在AbstractApplicationContext类的下述方法中会对BeanPostProcessor进行注册

registerBeanPostProcessors(ConfigurableListableBeanFactory beanFactory)
然后Spring会委托注册后置处理器的代理类PostProcessorRegistrationDelegate来注册BeanPostProcessor

public static void registerBeanPostProcessors(
ConfigurableListableBeanFactory beanFactory, AbstractApplicationContext applicationContext) {
//从Spring容器beanFactory中找到所有实现了BeanPostProcessor接口的类名称
String[] postProcessorNames = beanFactory.getBeanNamesForType(BeanPostProcessor.class, true, false);
//省略其余代码...
//通过类名称来创建具体的后置处理器 此处为伪代码 Spring中会将BeanPostProcessor分为多种类型的BeanPostProcessor接口
List<BeanPostProcessor> postProcessors = new ArrayList<>();
for (String ppName : postProcessorNames) {
BeanPostProcessor pp = beanFactory.getBean(ppName, BeanPostProcessor.class);
postProcessors.add(pp);
}
//获取到的后置处理器实例后,将其注册到beanFactory中
registerBeanPostProcessors(beanFactory, postProcessors);
//省略其余代码...
}
接着会遍历List数组

private static void registerBeanPostProcessors(
ConfigurableListableBeanFactory beanFactory, List<BeanPostProcessor> postProcessors) {

for (BeanPostProcessor postProcessor : postProcessors) {
    beanFactory.addBeanPostProcessor(postProcessor)
}

}
将后置处理器保存到AbstractBeanFactory类的下述属性中,在后续的初始化bean生命周期过程中会遍历所有后置处理,调用其postProcessBeforeInitialization和postProcessAfterInitialization方法

/** BeanPostProcessors to apply in createBean */
private final List<BeanPostProcessor> beanPostProcessors = new ArrayList<>();

@Override
public void addBeanPostProcessor(BeanPostProcessor beanPostProcessor) {
Assert.notNull(beanPostProcessor, "BeanPostProcessor must not be null");
this.beanPostProcessors.remove(beanPostProcessor);
//保存后置处理器
this.beanPostProcessors.add(beanPostProcessor);
}
Bean生命周期过程

后置处理器的调用就在bean的生命周期中完成,可参考BeanFactory接口类上的注释,了解bean的整个生命周期过程

在spring启动过程中,会有很多次调用getBean方法来创建或获取bean实例

@Override
public Object getBean(String name) throws BeansException {
return doGetBean(name, null, null, false);
}

@Override
public <T> T getBean(String name, @Nullable Class<T> requiredType) throws BeansException {
return doGetBean(name, requiredType, null, false);
}

@Override
public Object getBean(String name, Object... args) throws BeansException {
return doGetBean(name, null, args, false);
}
如果spring容器没有创建好名称为name的bean,就会先去调用下述方法去创建这个bean

AbstractAutowireCapableBeanFactory.createBean()
创建bean的过程中会先通过下述方法进行属性填充

populateBean(beanName, mbd, instanceWrapper)
填充完成以后,接着去调用下述方法初始化bean

AbstractAutowireCapableBeanFactory.initializeBean(beanName, exposedObject, mbd)
初始化bean的过程就是bean的生命周期执行过程,而后置处理器BeanPostProcessor的postProcessBeforeInitialization和postProcessAfterInitialization方法调用就在此过程中完成

protected Object initializeBean(final String beanName, final Object bean, @Nullable RootBeanDefinition mbd) {
//省略部分代码...
//调用Aware接口的setXXX方法
invokeAwareMethods(beanName, bean);

Object wrappedBean = bean;
if (mbd == null || !mbd.isSynthetic()) {
    //调用BeanPostProcessor接口的BeanPostProcessorsBeforeInitialization方法
    wrappedBean = applyBeanPostProcessorsBeforeInitialization(wrappedBean, beanName);
}

try {
    //调用自定义的init-method方法
    invokeInitMethods(beanName, wrappedBean, mbd);
}catch (Throwable ex) {
    throw new BeanCreationException(
            (mbd != null ? mbd.getResourceDescription() : null),
            beanName, "Invocation of init method failed", ex);
}
if (mbd == null || !mbd.isSynthetic()) {
    //调用BeanPostProcessor接口的postProcessAfterInitialization方法
    wrappedBean = applyBeanPostProcessorsAfterInitialization(wrappedBean, beanName);
}
return wrappedBean;

}
执行invokeAwareMethods时,会判断当前bean是否实现XXXAware接口,如果实现了XXXAware接口,则会去调用setXXX方法

private void invokeAwareMethods(final String beanName, final Object bean) {
if (bean instanceof Aware) {
if (bean instanceof BeanNameAware) {
((BeanNameAware) bean).setBeanName(beanName);
}
if (bean instanceof BeanClassLoaderAware) {
ClassLoader bcl = getBeanClassLoader();
if (bcl != null) {
((BeanClassLoaderAware) bean).setBeanClassLoader(bcl);
}
}
if (bean instanceof BeanFactoryAware) {
((BeanFactoryAware) bean).setBeanFactory(AbstractAutowireCapableBeanFactory.this);
}
}
}
执行applyBeanPostProcessorsBeforeInitialization方法,会遍历Spring容器中所有的后置处理器,而且会调用每个后置处理器的postProcessBeforeInitialization方法

@Override
public Object applyBeanPostProcessorsBeforeInitialization(Object existingBean, String beanName) throws BeansException {
Object result = existingBean;
for (BeanPostProcessor beanProcessor : getBeanPostProcessors()) {
Object current = beanProcessor.postProcessBeforeInitialization(result, beanName);
if (current == null) {
return result;
}
result = current;
}
return result;
}
执行invokeInitMethods方法,会先判断当前的bean有没有实现InitializingBean接口,如果实现了,则会调用InitializingBean接口的afterPropertiesSet()方法,然后判断是否自定义了init-method,如果有,则会执行其init-method

protected void invokeInitMethods(String beanName, final Object bean, @Nullable RootBeanDefinition mbd) throws Throwable {
//省略部分代码
//调用afterPropertiesSet方法
((InitializingBean) bean).afterPropertiesSet();

//判断如果自定义了init-method,就会执行init-method
if (mbd != null && bean.getClass() != NullBean.class) {
    String initMethodName = mbd.getInitMethodName();
    if (StringUtils.hasLength(initMethodName) &&
            !(isInitializingBean && "afterPropertiesSet".equals(initMethodName)) &&
            !mbd.isExternallyManagedInitMethod(initMethodName)) {
        invokeCustomInitMethod(beanName, bean, mbd);
    }
}

}
最后执行applyBeanPostProcessorsAfterInitialization方法,会遍历Spring容器中所有的后置处理器,而且会调用每个后置处理器的postProcessAfterInitialization方法

@Override
public Object applyBeanPostProcessorsAfterInitialization(Object existingBean, String beanName)
throws BeansException {

Object result = existingBean;
for (BeanPostProcessor beanProcessor : getBeanPostProcessors()) {
    Object current = beanProcessor.postProcessAfterInitialization(result, beanName);
    if (current == null) {
        return result;
    }
    result = current;
}
return result;

}
通过bean的生命周期执行过程,就可了解BeanPostProcessor的整个调用过程

©著作权归作者所有,转载或内容合作请联系作者
【社区内容提示】社区部分内容疑似由AI辅助生成,浏览时请结合常识与多方信息审慎甄别。
平台声明:文章内容(如有图片或视频亦包括在内)由作者上传并发布,文章内容仅代表作者本人观点,简书系信息发布平台,仅提供信息存储服务。

相关阅读更多精彩内容

友情链接更多精彩内容