Spring系列之BeanPostProcessor分析

Spring系列之Bean的生命周期及相关源码中,我们最后简单使用过BeanPostProcessor,这次我们就结合源码来具体谈谈这个BeanPostProcessor的作用。

实现BeanPostProcessor接口的类

public class TestBeanPostProcessor implements BeanPostProcessor {
    @Nullable
    @Override
    public Object postProcessBeforeInitialization(Object bean, String beanName) throws BeansException {
        System.out.println("postProcessBeforeInitialization——"+beanName+"——"+bean);
        return bean;
    }

    @Nullable
    @Override
    public Object postProcessAfterInitialization(Object bean, String beanName) throws BeansException {
        System.out.println("postProcessAfterInitialization————"+beanName+"——"+bean);
        return bean;
    }
}

然后我们看一下测试类

public class TestMain {
    @Test
    public void test(){
        AnnotationConfigApplicationContext applicationContext = new 
AnnotationConfigApplicationContext(TestConfig.class);
    }
}

我们可以看到除了我们自定义的Dog类被我们自定义的后置处理器TestBeanPostProcessor 增强了之外,还有几个默认的Bean也被增强了,那Spring容器中还有没有被我们自定义的后置处理器增强的Bean么,我们可以看一下Spring共有多个Bean存在。

控制bean的两种扩展方式

两种方式可以对bean做控制(例如修改某个成员变量)
1. 改变bean的定义(BeanFactoryPostProcessor接口) ,可以想象成修改了class文件,这样实例化出来的每个对象都变了;
2. 只改变实例化的对象(BeanPostProcessor接口);

源码分析:BeanPostProcessor接口的实现类如何被注册到spring容器

1. 从spring容器的初始化代码看起吧,看AbstractApplicationContext类的refresh方法,如下图所示,红框中的方法负责将BeanPostProcessor接口的实现类注册到spring容器:

2. 展开registerBeanPostProcessors方法,发现是委托PostProcessorRegistrationDelegate类的静态方法registerBeanPostProcessors来完成注册工作的:

protected void registerBeanPostProcessors(ConfigurableListableBeanFactory beanFactory) {
    PostProcessorRegistrationDelegate.registerBeanPostProcessors(beanFactory, this);
}

3. 展开PostProcessorRegistrationDelegate.registerBeanPostProcessors方法,里面的代码逻辑简洁整齐,意图目的一目了然:

public static void registerBeanPostProcessors(
        ConfigurableListableBeanFactory beanFactory, AbstractApplicationContext applicationContext) {
    //获取所有实现BeanPostProcessor接口的bean的名称
    String[] postProcessorNames = beanFactory.getBeanNamesForType(BeanPostProcessor.class, true, false);

    //注意,此时尽管注册操作还没有开始,但是之前已经有一些特殊的bean已经注册进来了,
    //详情请看AbstractApplicationContext类的prepareBeanFactory方法,
    //因此getBeanPostProcessorCount()方法返回的数量并不为零,
    //加一是因为方法末尾会注册一个ApplicationListenerDetector接口的实现类
    int beanProcessorTargetCount = beanFactory.getBeanPostProcessorCount() + 1 + postProcessorNames.length;
    //这里的BeanPostProcessorChecker也是个BeanPostProcessor的实现类,用于每个bean的初始化完成后,做一些简单的检查
    beanFactory.addBeanPostProcessor(new BeanPostProcessorChecker(beanFactory, beanProcessorTargetCount));

    //如果这些bean还实现了PriorityOrdered接口(在意执行顺序),就全部放入集合priorityOrderedPostProcessors 
    List<BeanPostProcessor> priorityOrderedPostProcessors = new ArrayList<BeanPostProcessor>();
    //集合internalPostProcessors,用来存放同时实现了PriorityOrdered和MergedBeanDefinitionPostProcessor接口的bean
    List<BeanPostProcessor> internalPostProcessors = new ArrayList<BeanPostProcessor>();
    //集合orderedPostProcessorNames用来存放实现了Ordered接口的bean的名称(在意执行顺序)
    List<String> orderedPostProcessorNames = new ArrayList<String>();
    //集合nonOrderedPostProcessorNames用来存放即没实现PriorityOrdered接口,也没有实现Ordered接口的bean的名称(不关心执行顺序)
    List<String> nonOrderedPostProcessorNames = new ArrayList<String>();
    for (String ppName : postProcessorNames) {
        if (beanFactory.isTypeMatch(ppName, PriorityOrdered.class)) {
            BeanPostProcessor pp = beanFactory.getBean(ppName, BeanPostProcessor.class);
            //实现了PriorityOrdered接口的bean,都放入集合priorityOrderedPostProcessors
            priorityOrderedPostProcessors.add(pp);
            if (pp instanceof MergedBeanDefinitionPostProcessor) {
                //实现了MergedBeanDefinitionPostProcessor接口的bean,都放入internalPostProcessors集合
                internalPostProcessors.add(pp);
            }
        }
        else if (beanFactory.isTypeMatch(ppName, Ordered.class)) {
            //实现了Ordered接口的bean,将其名称都放入orderedPostProcessorNames集合
            orderedPostProcessorNames.add(ppName);
        }
        else {
            //既没实现PriorityOrdered接口,也没有实现Ordered接口的bean,将其名称放入nonOrderedPostProcessorNames集合
            nonOrderedPostProcessorNames.add(ppName);
        }
    }

    //实现了PriorityOrdered接口的bean排序
    OrderComparator.sort(priorityOrderedPostProcessors);
    //注册到容器
    registerBeanPostProcessors(beanFactory, priorityOrderedPostProcessors);

    List<BeanPostProcessor> orderedPostProcessors = new ArrayList<BeanPostProcessor>();
    //处理所有实现了Ordered接口的bean
    for (String ppName : orderedPostProcessorNames) {
        BeanPostProcessor pp = beanFactory.getBean(ppName, BeanPostProcessor.class);
        orderedPostProcessors.add(pp);
        //前面将所有实现了PriorityOrdered和MergedBeanDefinitionPostProcessor的bean放入internalPostProcessors,
        //此处将所有实现了Ordered和MergedBeanDefinitionPostProcessor的bean放入internalPostProcessors
        if (pp instanceof MergedBeanDefinitionPostProcessor) {
            internalPostProcessors.add(pp);
        }
    }

    //实现了Ordered接口的bean排序
    OrderComparator.sort(orderedPostProcessors);
    //注册到容器
    registerBeanPostProcessors(beanFactory, orderedPostProcessors);

    List<BeanPostProcessor> nonOrderedPostProcessors = new ArrayList<BeanPostProcessor>();
    for (String ppName : nonOrderedPostProcessorNames) {
        BeanPostProcessor pp = beanFactory.getBean(ppName, BeanPostProcessor.class);
        nonOrderedPostProcessors.add(pp);
        //此处将其余实现了MergedBeanDefinitionPostProcessor的bean放入internalPostProcessors
        if (pp instanceof MergedBeanDefinitionPostProcessor) {
            internalPostProcessors.add(pp);
        }
    }
    //注册到容器
    registerBeanPostProcessors(beanFactory, nonOrderedPostProcessors);

    OrderComparator.sort(internalPostProcessors);
    //将所有实现了MergedBeanDefinitionPostProcessor接口的bean也注册到容器
    registerBeanPostProcessors(beanFactory, internalPostProcessors);
    //创建一个ApplicationListenerDetector对象并且注册到容器,这就是前面计算beanProcessorTargetCount的值时加一的原因
    beanFactory.addBeanPostProcessor(new ApplicationListenerDetector(applicationContext));
}

以上代码已加注释,就不多解读了,有一点需要注意:对于实现了MergedBeanDefinitionPostProcessor接口的bean,在前面几次调用registerBeanPostProcessors方法的时候已经注册过了,那么在最后执行的registerBeanPostProcessors(beanFactory, internalPostProcessors),岂不是将一个bean注册了多次?

为了弄清楚这个问题需要看registerBeanPostProcessors方法:

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

    for (BeanPostProcessor postProcessor : postProcessors) {
        //对每个bean都调用beanFactory.addBeanPostProcessor方法来注册
        beanFactory.addBeanPostProcessor(postProcessor);
    }
}

addBeanPostProcessor方法的代码在AbstractApplicationContext类中,如下所示,先删除再添加,这样反复注册也没有问题

@Override
public void addBeanPostProcessor(BeanPostProcessor beanPostProcessor) {
    Assert.notNull(beanPostProcessor, "BeanPostProcessor must not be null");
    //如果已经注册,就先删除掉
    this.beanPostProcessors.remove(beanPostProcessor);
    //再注册
    this.beanPostProcessors.add(beanPostProcessor);
    if (beanPostProcessor instanceof InstantiationAwareBeanPostProcessor) {
        this.hasInstantiationAwareBeanPostProcessors = true;
    }
    if (beanPostProcessor instanceof DestructionAwareBeanPostProcessor) {
        this.hasDestructionAwareBeanPostProcessors = true;
    }
}

至此,我们已经弄清楚了BeanPostProcessor实现类的bean注册到spring容器的逻辑,接下来看看spring容器如何使用这些bean;

源码分析,BeanPostProcessor实现类如何被使用

1. 要弄清楚BeanPostProcessor接口的实现类是在哪里被用到的,还是从负责容器初始化的AbstractApplicationContext类的refresh方法看起,如下图红框中的finishBeanFactoryInitialization方法,就是负责实例化和初始化bean的:

2. 从finishBeanFactoryInitialization方法到BeanPostProcessor的实现类被使用,中间有多层逻辑和调用,篇幅所限就不逐个展开了,直接列出堆栈信息,您可以根据此信息去查看对应源码:

org.springframework.beans.factory.support.AbstractAutowireCapableBeanFactory.initializeBean()
org.springframework.beans.factory.support.AbstractAutowireCapableBeanFactory.doCreateBean()
org.springframework.beans.factory.support.AbstractAutowireCapableBeanFactory.createBean()
org.springframework.beans.factory.support.AbstractBeanFactory$1.getObject()
org.springframework.beans.factory.support.DefaultSingletonBeanRegistry.getSingleton()
org.springframework.beans.factory.support.AbstractBeanFactory.doGetBean()
org.springframework.beans.factory.support.AbstractBeanFactory.getBean()
org.springframework.beans.factory.support.DefaultListableBeanFactory.preInstantiateSingletons()
org.springframework.context.support.AbstractApplicationContext.finishBeanFactoryInitialization()
org.springframework.context.support.AbstractApplicationContext.refresh()
org.springframework.boot.context.embedded.EmbeddedWebApplicationContext.refresh()
org.springframework.boot.SpringApplication.refresh()
org.springframework.boot.SpringApplication.refreshContext()
org.springframework.boot.SpringApplication.run()
org.springframework.boot.SpringApplication.run()
org.springframework.boot.SpringApplication.run()

3. 根据上述堆栈信息,直接查看AbstractAutowireCapableBeanFactory类的initializeBean()方法:

protected Object initializeBean(final String beanName, final Object bean, RootBeanDefinition mbd) {
    if (System.getSecurityManager() != null) {
        AccessController.doPrivileged(new PrivilegedAction<Object>() {
            @Override
            public Object run() {
                invokeAwareMethods(beanName, bean);
                return null;
            }
        }, getAccessControlContext());
    }
    else {
        invokeAwareMethods(beanName, bean);
    }

    Object wrappedBean = bean;
    if (mbd == null || !mbd.isSynthetic()) {
        //对已经实例化的bean,在初始化前用BeanPostProcessor实现类去处理
        wrappedBean = applyBeanPostProcessorsBeforeInitialization(wrappedBean, beanName);
    }

    try {
        //bean的初始化
        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()) {
        //对已经实例化的bean,在初始化后用BeanPostProcessor实现类去处理
        wrappedBean = applyBeanPostProcessorsAfterInitialization(wrappedBean, beanName);
    }
    return wrappedBean;
}

如上所示,我们最关注的代码是applyBeanPostProcessorsBeforeInitialization和applyBeanPostProcessorsAfterInitialization这两个方法,它们分别在bean的初始化方法invokeInitMethods的前后被执行;

4. 先看看applyBeanPostProcessorsBeforeInitialization方法,逻辑非常简单,就是取出所有已注册的BeanPostProcessor实现类,执行其postProcessBeforeInitialization方法,入参是当前正在做实例化和初始化的bean实例:

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

    Object result = existingBean;
    //逐一执行每个BeanPostProcessor实现类的postProcessBeforeInitialization方法
    for (BeanPostProcessor beanProcessor : getBeanPostProcessors()) {
        result = beanProcessor.postProcessBeforeInitialization(result, beanName);
        if (result == null) {
            return result;
        }
    }
    return result;
}

5. 在invokeInitMethods方法执行完毕后会执行applyBeanPostProcessorsAfterInitialization方法,代码如下,与applyBeanPostProcessorsBeforeInitialization如出一辙,仅有的不同是调用的beanProcessor的方法变成了postProcessAfterInitialization:

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

    Object result = existingBean;
    //逐一执行每个BeanPostProcessor实现类的postProcessAfterInitialization方法
    for (BeanPostProcessor beanProcessor : getBeanPostProcessors()) {
        result = beanProcessor.postProcessAfterInitialization(result, beanName);
        if (result == null) {
            return result;
        }
    }
    return result;
}

以上就是spring容器初始化过程中对BeanPostProcessor实现类的使用场景,此时还剩一点疑问需要澄清:在分析注册过程的时候,曾看到实现MergedBeanDefinitionPostProcessor接口的bean是最后注册的,那么这些MergedBeanDefinitionPostProcessor实现类在spring容器中是何处使用的呢?
为了搞清这个问题,来看看AbstractAutowireCapableBeanFactory类的doCreateBean方法,前面我们分析的initializeBean方法就是在这里面被调用的:

如上图所示,红框中就是用所有MergedBeanDefinitionPostProcessor实现类去处理当前正在实例化的bean,然后才会执行绿框中的initializeBean方法(里面是我们刚才分析的bean的初始化,BeanPostProcessor实现类被使用的逻辑);
来看看红框中的applyMergedBeanDefinitionPostProcessors方法,主要目的是处理特殊的合成bean的定义类:

protected void applyMergedBeanDefinitionPostProcessors(RootBeanDefinition mbd, Class<?> beanType, String beanName)
            throws BeansException {

    try {
        //取出每个注册的BeanPostProcessor实现类
        for (BeanPostProcessor bp : getBeanPostProcessors()) {
            //只有实现了MergedBeanDefinitionPostProcessor接口才执行
            if (bp instanceof MergedBeanDefinitionPostProcessor) {
                MergedBeanDefinitionPostProcessor bdp = (MergedBeanDefinitionPostProcessor) bp;
                //执行postProcessMergedBeanDefinition
                bdp.postProcessMergedBeanDefinition(mbd, beanType, beanName);
            }
        }
    }
    catch (Exception ex) {
        throw new BeanCreationException(mbd.getResourceDescription(), beanName,
                "Post-processing failed of bean type [" + beanType + "] failed", ex);
    }
}


至此,我们对BeanPostProcessor有关的源码分析就完成了,小结一下:
1. 初始化时,spring容器有特别处理,会直接调用beanFactory.addBeanPostProcessor进行注册(例如AbstractApplicationContext类的prepareBeanFactory方法中就有);
2. 找出所有实现了BeanPostProcessor接口的bean,注册到容器,注册顺序如下:
第一:实现了PriorityOrdered接口的,排序后;
第二:实现了Ordered接口的,排序后;
第三:既没实现PriorityOrdered接口,也没有实现Ordered接口的;
第四:实现了MergedBeanDefinitionPostProcessor接口的(这些也按照PriorityOrdered、Ordered等逻辑拍过续);
第五:实例化一个ApplicationListenerDetector对象;
3. 实例化bean的时候,对于每个bean,先用MergedBeanDefinitionPostProcessor实现类的postProcessMergedBeanDefinition方法处理每个bean的定义类;
4. 再用BeanPostProcessor的postProcessBeforeInitialization方法处理每个bean实例;
5. bean实例初始化;
6. 用BeanPostProcessor的postProcessAfterInitialization方法处理每个bean实例;

源码分析结束,接下来自定义一个BeanPostProcessor实现类,验证我们之前的分析:控制bean实例;

 

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值