Spring ApplicationContext(六)BeanPostProcessor

Spring ApplicationContext(六)BeanPostProcessor

产生回顾一下 ApplicationContext 初始化的几个步骤:第一步是刷新环境变量;第二步是刷新 beanFactory 并加载 BeanDefinition;第三步是对 beanFactory 进行功能扩展,如增加 SPEL 支持和属性编辑器;第四步是留给子类实现的。

上一节中向 Spring 中注册将执行了 BeanFactoryPostProcessor,本节则继续探讨一下 BeanPostProcessor 的注册及调用时机。

public interface BeanPostProcessor {
    // 在初始化之前调用
    Object postProcessBeforeInitialization(Object bean, String beanName) throws BeansException;
    // 在初始化之后调用
    Object postProcessAfterInitialization(Object bean, String beanName) throws BeansException;
}
  1. BeanPostProcessor 什么时候注册?

BeanFactory 和 ApplicationContext 容器的注册方式不大一样:若使用 BeanFactory,则必须要显示的调用其 addBeanPostProcessor() 方法进行注册;如果是使用 ApplicationContext,那么容器会在配置文件在中自动寻找实现了 BeanPostProcessor 接口的 Bean,然后自动注册。

  1. BeanPostProcessor 如何确保调用顺序?

假如我们使用了多个的 BeanPostProcessor 的实现类,那么如何确定处理顺序呢?其实只要实现 Ordered 接口,设置 order 属性就可以很轻松的确定不同实现类的处理顺序了;
接口中的两个方法都要将传入的 bean 返回,而不能返回 null,如果返回的是 null 那么我们通过 getBean() 方法将得不到目标。

一、BeanPostProcessor 的注册

源代码【AbstractApplicationContext】

@Override
public void refresh() throws BeansException, IllegalStateException {
    // 6. 注册 BeanPostProcessor 后置处理器,在 getBean() 创建 bean 时调用
    registerBeanPostProcessors(beanFactory);

    /**
    * 1. 实例化剩余的所有非延迟加载单例对象
    * 2. 为什么说是剩余的?因为在上面的 registerBeanPostProcessors 中已经把所有 BeanPostProcessors 所有对象都已经实例化过了;
    * 3. 这加载的时候会判断 bean 是不是 FactoryBean 类型的
    *   3.1 如果是 FactoryBean 类型,则 getBean(&beanName),这里是把 FactoryBean 本身的对象给实例化了,而没有调它的 getObject 方法;
    *   3.2 如果不是 FactoryBean 类型,直接 getBean() 就行了;
    * 4. 还要判断是不是 SmartInitializingSingleton 接口,这个接口有个 afterSingletonsInstantiated 方法;
    */
    finishBeanFactoryInitialization(beanFactory);
}

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

源代码【PostProcessorRegistrationDelegate】

public static void registerBeanPostProcessors(
            ConfigurableListableBeanFactory beanFactory, AbstractApplicationContext applicationContext) {
    // 1. 此时 BeanDefinition 已经加载,只是 bean 还没有被实例化
    String[] postProcessorNames = beanFactory.getBeanNamesForType(BeanPostProcessor.class, true, false);

    // 2. 记录日志用
    // 可能已经注册了部分 BeanFactoryPostProcessors 接口
    int beanProcessorTargetCount = beanFactory.getBeanPostProcessorCount() + 1 + postProcessorNames.length;
    beanFactory.addBeanPostProcessor(new BeanPostProcessorChecker(beanFactory, beanProcessorTargetCount));

    // 3. 按 PriorityOrdered internal Ordered nonOrdered 四个级别
    // 3.1 优先级最高的 BeanPostProcessors,这类最先调用;需要实现 PriorityOrdered 接口
    List<BeanPostProcessor> priorityOrderedPostProcessors = new ArrayList<BeanPostProcessor>();
    // 3.2 内部 BeanPostProcessors
    List<BeanPostProcessor> internalPostProcessors = new ArrayList<BeanPostProcessor>();
    // 3.3 继承了 Ordered 接口,优先级比上面低一点
    List<String> orderedPostProcessorNames = new ArrayList<String>();
    // 3.4 这就是普通的了,优先级最低
    List<String> nonOrderedPostProcessorNames = new ArrayList<String>();
    for (String ppName : postProcessorNames) {
        if (beanFactory.isTypeMatch(ppName, PriorityOrdered.class)) {
            BeanPostProcessor pp = beanFactory.getBean(ppName, BeanPostProcessor.class);
            priorityOrderedPostProcessors.add(pp);
            if (pp instanceof MergedBeanDefinitionPostProcessor) {
                internalPostProcessors.add(pp);
            }
        }
        else if (beanFactory.isTypeMatch(ppName, Ordered.class)) {
            orderedPostProcessorNames.add(ppName);
        }
        else {
            nonOrderedPostProcessorNames.add(ppName);
        }
    }

    // 4. PriorityOrdered internal Ordered nonOrdered 分别排序、初始化、注册
    // 4.1 PriorityOrdered BeanPostProcessors
    sortPostProcessors(beanFactory, priorityOrderedPostProcessors);
    registerBeanPostProcessors(beanFactory, priorityOrderedPostProcessors);

    // 4.2 Ordered BeanPostProcessors
    List<BeanPostProcessor> orderedPostProcessors = new ArrayList<BeanPostProcessor>();
    for (String ppName : orderedPostProcessorNames) {
        BeanPostProcessor pp = beanFactory.getBean(ppName, BeanPostProcessor.class);
        orderedPostProcessors.add(pp);
        if (pp instanceof MergedBeanDefinitionPostProcessor) {
            internalPostProcessors.add(pp);
        }
    }
    sortPostProcessors(beanFactory, orderedPostProcessors);
    registerBeanPostProcessors(beanFactory, orderedPostProcessors);

    // 4.3 nonOrdered BeanPostProcessors
    List<BeanPostProcessor> nonOrderedPostProcessors = new ArrayList<BeanPostProcessor>();
    for (String ppName : nonOrderedPostProcessorNames) {
        BeanPostProcessor pp = beanFactory.getBean(ppName, BeanPostProcessor.class);
        nonOrderedPostProcessors.add(pp);
        if (pp instanceof MergedBeanDefinitionPostProcessor) {
            internalPostProcessors.add(pp);
        }
    }
    registerBeanPostProcessors(beanFactory, nonOrderedPostProcessors);

    // 4.4 internal BeanPostProcessors
    //     注意重复注册会先删除先注册的元素加添加到集合最后面,影响执行顺序
    sortPostProcessors(beanFactory, internalPostProcessors);
    registerBeanPostProcessors(beanFactory, internalPostProcessors);

    beanFactory.addBeanPostProcessor(new ApplicationListenerDetector(applicationContext));
}

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

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

源代码【AbstractBeanFactory】

private final List<BeanPostProcessor> beanPostProcessors = new ArrayList<BeanPostProcessor>();

@Override
public void addBeanPostProcessor(BeanPostProcessor beanPostProcessor) {
    Assert.notNull(beanPostProcessor, "BeanPostProcessor must not be null");
    // 如果已经注册则删除后重新注册,影响其执行顺序,如 internal 中的 MergedBeanDefinitionPostProcessor
    this.beanPostProcessors.remove(beanPostProcessor);
    this.beanPostProcessors.add(beanPostProcessor);
    if (beanPostProcessor instanceof InstantiationAwareBeanPostProcessor) {
        this.hasInstantiationAwareBeanPostProcessors = true;
    }
    if (beanPostProcessor instanceof DestructionAwareBeanPostProcessor) {
        this.hasDestructionAwareBeanPostProcessors = true;
    }
}

总结:

(1) 最后 BeanPostProcessor 的注册顺序为 PriorityOrdered、Ordered、nonOrdered、internal,其中 internal 又分为 PriorityOrdered、Ordered、nonOrdered 三种顺序。

二、BeanPostProcessor 实战

class PriorityOrderTest implements BeanPostProcessor, PriorityOrdered {}

class OrderTest implements BeanPostProcessor, Ordered {}

class NoneTest implements BeanPostProcessor {}

三、BeanPostProcessor 调用时机

源代码【AbstractAutowireCapableBeanFactory】

protected Object doCreateBean(final String beanName, final RootBeanDefinition mbd, final Object[] args) {
    //省略...
    populateBean(beanName, mbd, instanceWrapper);
    if (exposedObject != null) {
        // BeanPostProcessors 两个方法都在这里面
        exposedObject = initializeBean(beanName, exposedObject, mbd);
    }
}

protected Object initializeBean(final String beanName, final Object bean, RootBeanDefinition mbd) {
    // 省略 ...
    invokeAwareMethods(beanName, bean);

    Object wrappedBean = bean;
    if (mbd == null || !mbd.isSynthetic()) {
        // 初始化前
        wrappedBean = applyBeanPostProcessorsBeforeInitialization(wrappedBean, beanName);
    }

    try {
        // 初始化
        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()) {
        // 初始化后
        wrappedBean = applyBeanPostProcessorsAfterInitialization(wrappedBean, beanName);
    }
    return wrappedBean;
}

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

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

每天用心记录一点点。内容也许不重要,但习惯很重要!

posted on 2019-02-23 18:17  binarylei  阅读(899)  评论(0编辑  收藏  举报

导航