Spring ApplicationContext(六)BeanPostProcessor

Spring ApplicationContext(六)BeanPostProcessor

產生回顧一下 ApplicationContext 初始化的幾個步驟:第一步是刷新環境變量;第二步是刷新 beanFactory 並加載 BeanDefinition;第三步是對 beanFactory 進行功能擴展,如增長 SPEL 支持和屬性編輯器;第四步是留給子類實現的。java

上一節中向 Spring 中註冊將執行了 BeanFactoryPostProcessor,本節則繼續探討一下 BeanPostProcessor 的註冊及調用時機。spring

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,而後自動註冊。app

  1. BeanPostProcessor 如何確保調用順序?

假如咱們使用了多個的 BeanPostProcessor 的實現類,那麼如何肯定處理順序呢?其實只要實現 Ordered 接口,設置 order 屬性就能夠很輕鬆的肯定不一樣實現類的處理順序了;
接口中的兩個方法都要將傳入的 bean 返回,而不能返回 null,若是返回的是 null 那麼咱們經過 getBean() 方法將得不到目標。編輯器

1、BeanPostProcessor 的註冊

源代碼【AbstractApplicationContext】ide

@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】post

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】this

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 三種順序。code

2、BeanPostProcessor 實戰

class PriorityOrderTest implements BeanPostProcessor, PriorityOrdered {}

class OrderTest implements BeanPostProcessor, Ordered {}

class NoneTest implements BeanPostProcessor {}

3、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;
}

天天用心記錄一點點。內容也許不重要,但習慣很重要!

相關文章
相關標籤/搜索