Spring擴展點之BeanPostProcessor

前言

BeanPostProcessor接口是Spring中一個很是重要的接口,它的接口定義以下segmentfault

public interface BeanPostProcessor {

    Object postProcessBeforeInitialization(Object bean, String beanName) throws BeansException;
    
    Object postProcessAfterInitialization(Object bean, String beanName) throws BeansException;
}

當你實現了這個接口的時候,Spring會保證在每個bean對象初始化方法調用以前調用postProcessBeforeInitialization方法,在初始化方法調用以後調用postProcessAfterInitializationapp

BeanPostProcessor的註冊

看過我以前寫的IOC源碼分析系列文章的同窗應該對這個都比較有印象
1)
Spring在執行到這的時候會把全部實現BeanPostProcessor接口的實現類都註冊到BeanFactory中,一塊兒來看一下實現的細節ide

protected void registerBeanPostProcessors(ConfigurableListableBeanFactory beanFactory) {
        PostProcessorRegistrationDelegate.registerBeanPostProcessors(beanFactory, this);
    }
public static void registerBeanPostProcessors(
            ConfigurableListableBeanFactory beanFactory, AbstractApplicationContext applicationContext) {
        //獲取全部BeanPostProcessor的實現類
        String[] postProcessorNames = beanFactory.getBeanNamesForType(BeanPostProcessor.class, true, false);


        int beanProcessorTargetCount = beanFactory.getBeanPostProcessorCount() + 1 + postProcessorNames.length;
        beanFactory.addBeanPostProcessor(new BeanPostProcessorChecker(beanFactory, beanProcessorTargetCount));

          // 這裏把實現PriorityOrdered接口,Ordered 接口的BeanPostProcessors 和其餘類型的BeanPostProcessors 區分開
        List<BeanPostProcessor> priorityOrderedPostProcessors = new ArrayList<>();
        List<BeanPostProcessor> internalPostProcessors = new ArrayList<>();
        List<String> orderedPostProcessorNames = new ArrayList<>();
        List<String> nonOrderedPostProcessorNames = new ArrayList<>();
        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);
            }
        }

        //對實現了PriorityOrdered接口的按優先級排序
        sortPostProcessors(beanFactory, priorityOrderedPostProcessors);
       //這裏就是註冊了,下面會說
        registerBeanPostProcessors(beanFactory, priorityOrderedPostProcessors);

        
        List<BeanPostProcessor> orderedPostProcessors = new ArrayList<>();
        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);

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

        // 最後註冊常規的
        sortPostProcessors(beanFactory, internalPostProcessors);
        registerBeanPostProcessors(beanFactory, internalPostProcessors);

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

能夠看到上方的代碼就是把這些BeanPostProcessor分爲了幾類,而後分別根據規則排序後註冊進BeanFactory中,而BeanFactory中其實就只是維護了一個BeanPostProcessor的列表而已源碼分析

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

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

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

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

    }

執行原理

咱們知道Bean的初始化是在定義在容器的刷新過程當中,而具體的實現則是由AbstractAutowireCapableBeanFactory.initializeBean()方法完成的。在這個方法中就包含了BeanPostProcessor的調用邏輯post

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()) {
            // BeanPostProcessors 的Before 方法
            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()) {
            // BeanPostProcessors 的After方法
            wrappedBean = applyBeanPostProcessorsAfterInitialization(wrappedBean, beanName);
        }
        return wrappedBean;
    }

而這裏面的執行邏輯咱們也能夠猜到,無非就是循環遍歷全部的BeanPostProcessor,而後一一執行this

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

其中applyBeanPostProcessorsAfterInitialization的實現內容跟這個是同樣的spa

可是這裏面有一個主意的點,那就是若是具體的實現一但返回null,那麼就會跳出for循環,後面的就得不到機會執行了code

常見用例

查看這個接口的繼承體系,能夠看到這個接口的實現類是很是多的,各個實現類的功能若是感興趣你們能夠去慢慢挖掘一下
2對象

1

相關文章
相關標籤/搜索