1. 程式人生 > >(五)關於BeanPostProcessor各個回撥的時機

(五)關於BeanPostProcessor各個回撥的時機

1、BeanPostProcessor的五大介面

這裡寫圖片描述

一共有11個回撥方法

1.1.BeanPostProcessor

關於物件初始化前後的回撥。
public interface BeanPostProcessor {
    //該方法在bean例項化完畢(且已經注入完畢),在afterPropertiesSet或自定義init方法執行之前
    @Nullable
    default Object postProcessBeforeInitialization(Object bean, String beanName) throws BeansException {
        return
bean; } //在afterPropertiesSet或自定義init方法執行之後 @Nullable default Object postProcessAfterInitialization(Object bean, String beanName) throws BeansException { return bean; } }

1.2.InstantiationAwareBeanPostProcessor

關於物件例項化前後以及例項化後設置propertyValues的回撥
public interface InstantiationAwareBeanPostProcessor
extends BeanPostProcessor {
//這個方法用來在物件例項化前直接返回一個物件(如代理物件)來代替通過內建的例項化流程建立物件; @Nullable default Object postProcessBeforeInstantiation(Class<?> beanClass, String beanName) throws BeansException { return null; } //在物件例項化完畢執行populateBean之前 如果返回false則spring不再對對應的bean例項進行自動依賴注入。
default boolean postProcessAfterInstantiation(Object bean, String beanName) throws BeansException { return true; } //這裡是在spring處理完預設的成員屬性,應用到指定的bean之前進行回撥,可以用來檢查和修改屬性,最終返回的PropertyValues會應用到bean中 //@Autowired、@Resource等就是根據這個回撥來實現最終注入依賴的屬性的。 @Nullable default PropertyValues postProcessPropertyValues( PropertyValues pvs, PropertyDescriptor[] pds, Object bean, String beanName) throws BeansException { return pvs; } }

1.3.SmartInstantiationAwareBeanPostProcessor

這個介面主要是spring框架內部來使用
public interface SmartInstantiationAwareBeanPostProcessor extends InstantiationAwareBeanPostProcessor {
    //用來返回目標物件的型別(比如代理物件通過raw class獲取proxy type 用於型別匹配)
    @Nullable
    default Class<?> predictBeanType(Class<?> beanClass, String beanName) throws BeansException {
        return null;
    }
    //這裡提供一個拓展點用來解析獲取用來例項化的構造器(比如未通過bean定義構造器以及引數的情況下,會根據這個回撥來確定構造器)
    @Nullable
    default Constructor<?>[] determineCandidateConstructors(Class<?> beanClass, String beanName)
            throws BeansException {
        return null;
    }
    //獲取要提前暴露的bean的引用,用來支援單例物件的迴圈引用(一般是bean自身,如果是代理物件則需要取用代理引用)
    default Object getEarlyBeanReference(Object bean, String beanName) throws BeansException {
        return bean;
    }
}

1.4.MergedBeanDefinitionPostProcessor

用來將merged BeanDefinition暴露出來的回撥
public interface MergedBeanDefinitionPostProcessor extends BeanPostProcessor {
    //在bean例項化完畢後呼叫 可以用來修改merged BeanDefinition的一些properties 或者用來給後續回撥中快取一些meta資訊使用
    //這個算是將merged BeanDefinition暴露出來的一個回撥
    void postProcessMergedBeanDefinition(RootBeanDefinition beanDefinition, Class<?> beanType, String beanName);
}

1.5.DestructionAwareBeanPostProcessor

關於處理物件銷燬的前置回撥
應用例項:
    ApplicationListenerDetector,這個類是用來註冊ApplicationListener例項的,而如果銷燬一個物件,不接觸這裡的引用
    會導致無法進行回收,因此在銷燬物件時,會判斷如果是ApplicationListener要執行從監聽器列表中移除掉。
public interface DestructionAwareBeanPostProcessor extends BeanPostProcessor {
    //這裡實現銷燬物件的邏輯
    void postProcessBeforeDestruction(Object bean, String beanName) throws BeansException;
    //判斷是否需要處理這個物件的銷燬
    default boolean requiresDestruction(Object bean) {
        return true;
    }
}

2.關於BeanPostProcessor中各個回撥呼叫的順序

1、InstantiationAwareBeanPostProcessor.postProcessBeforeInstantiation(beanClass, beanName)
    該方法在建立物件之前會先掉用,如果有返回例項則直接使用不會去走下面建立物件的邏輯,並在之後執行
        BeanPostProcessor.postProcessAfterInitialization(result, beanName)
2、SmartInstantiationAwareBeanPostProcessor.determineCandidateConstructors(beanClass, beanName)
    如果需要的話,會在例項化物件之前執行
3、MergedBeanDefinitionPostProcessor.postProcessMergedBeanDefinition(mbd, beanType, beanName)
    在物件例項化完畢 初始化之前執行
4、InstantiationAwareBeanPostProcessor.postProcessAfterInstantiation(bw.getWrappedInstance(), beanName)
    在bean建立完畢初始化之前執行
5、InstantiationAwareBeanPostProcessor.postProcessPropertyValues(pvs, filteredPds, bw.getWrappedInstance(), beanName)
    在bean的property屬性注入完畢 向bean中設定屬性之前執行
6、BeanPostProcessor.postProcessBeforeInitialization(result, beanName)
    在bean初始化(自定義init或者是實現了InitializingBean.afterPropertiesSet())之前執行
7、BeanPostProcessor.postProcessAfterInitialization(result, beanName)
    在bean初始化(自定義init或者是實現了InitializingBean.afterPropertiesSet())之後執行
8、其中DestructionAwareBeanPostProcessor方法的postProcessBeforeDestruction(Object bean, String beanName)會在銷燬物件前執行


DestructionAwareBeanPostProcessor 中的requiresDestruction(Object bean)是用來判斷是否屬於當前processor處理的bean
SmartInstantiationAwareBeanPostProcessor中的predictBeanType(Class<?> beanClass, String beanName)是用來預判型別的
SmartInstantiationAwareBeanPostProcessor.getEarlyBeanReference(exposedObject, beanName)
    這個方法僅僅是在這一步是作為一個ObjectFactory封裝起來放到singletonFactories中的,
    僅在併發情況下 剛好在當前物件設定進去,而另一個bean建立需要getBean獲取時才會立即執行
    因此這一步的順序是不一定的,有可能永遠不會執行(無併發循壞依賴物件建立的場景)
    可能在3之後物件例項化完畢執行addSingleton(beanName, singletonObject);之前執行到
因此這三個方法沒有嚴格的順序意義

3.驗證執行順序

@Configuration
public class Application {

    public static void main(String[] args) {
        AnnotationConfigApplicationContext applicationContext = new AnnotationConfigApplicationContext(Application.class);
        applicationContext.registerBeanDefinition("demoBean", new RootBeanDefinition(DemoBean.class));
        applicationContext.getBean("demoBean");
        applicationContext.start();
        applicationContext.destroy();
    }

    @Bean
    public BeanPostProcessor fullyPostProcessor() {
        return new FullyBeanPostProcessor();
    }

    public static class DemoBean {

    }

    @Order
    public class FullyBeanPostProcessor implements BeanPostProcessor,
            InstantiationAwareBeanPostProcessor,
            SmartInstantiationAwareBeanPostProcessor,
            MergedBeanDefinitionPostProcessor,
            DestructionAwareBeanPostProcessor {
        @Override
        public Object postProcessBeforeInstantiation(Class<?> beanClass, String beanName) throws BeansException {
            if (beanClass == DemoBean.class) {
                System.out.println("1 --> InstantiationAwareBeanPostProcessor.postProcessBeforeInstantiation(beanClass, beanName)");
            }
            return null;
        }

        @Override
        public Constructor<?>[] determineCandidateConstructors(Class<?> beanClass, String beanName) throws BeansException {
            if (beanClass == DemoBean.class) {
                System.out.println("2 --> SmartInstantiationAwareBeanPostProcessor.determineCandidateConstructors(beanClass, beanName)");
            }
            return null;
        }

        @Override
        public void postProcessMergedBeanDefinition(RootBeanDefinition beanDefinition, Class<?> beanType, String beanName) {
            if (beanType == DemoBean.class) {
                System.out.println("3 --> MergedBeanDefinitionPostProcessor.postProcessMergedBeanDefinition(mbd, beanType, beanName)");
            }

        }

        @Override
        public boolean postProcessAfterInstantiation(Object bean, String beanName) throws BeansException {
            if (bean instanceof DemoBean) {
                System.out.println("4 --> InstantiationAwareBeanPostProcessor.postProcessAfterInstantiation(bw.getWrappedInstance(), beanName)");
            }
            return true;
        }

        @Override
        public PropertyValues postProcessPropertyValues(PropertyValues pvs, PropertyDescriptor[] pds, Object bean, String beanName) throws BeansException {
            if (bean instanceof DemoBean) {
                System.out.println("5 --> InstantiationAwareBeanPostProcessor.postProcessPropertyValues(pvs, filteredPds, bw.getWrappedInstance(), beanName)");
            }
            return pvs;
        }

        @Override
        public Object postProcessBeforeInitialization(Object bean, String beanName) throws BeansException {
            if (bean instanceof DemoBean) {
                System.out.println("6 --> BeanPostProcessor.postProcessBeforeInitialization(result, beanName)");
            }
            return bean;
        }

        @Override
        public Object postProcessAfterInitialization(Object bean, String beanName) throws BeansException {
            if (bean instanceof DemoBean) {
                System.out.println("7 --> BeanPostProcessor.postProcessAfterInitialization(result, beanName)");
            }
            return bean;
        }

        @Override
        public void postProcessBeforeDestruction(Object bean, String beanName) throws BeansException {
            if (bean instanceof DemoBean) {
                System.out.println("8 --> DestructionAwareBeanPostProcessor.postProcessBeforeDestruction(Object bean, String beanName)");
            }
        }

        @Override
        public Class<?> predictBeanType(Class<?> beanClass, String beanName) throws BeansException {
            return null;
        }


        @Override
        public Object getEarlyBeanReference(Object bean, String beanName) throws BeansException {
            return bean;
        }
    }
}
最終輸出結果:
    1 --> InstantiationAwareBeanPostProcessor.postProcessBeforeInstantiation(beanClass, beanName)
    2 --> SmartInstantiationAwareBeanPostProcessor.determineCandidateConstructors(beanClass, beanName)
    3 --> MergedBeanDefinitionPostProcessor.postProcessMergedBeanDefinition(mbd, beanType, beanName)
    4 --> InstantiationAwareBeanPostProcessor.postProcessAfterInstantiation(bw.getWrappedInstance(), beanName)
    5 --> InstantiationAwareBeanPostProcessor.postProcessPropertyValues(pvs, filteredPds, bw.getWrappedInstance(), beanName)
    6 --> BeanPostProcessor.postProcessBeforeInitialization(result, beanName)
    7 --> BeanPostProcessor.postProcessAfterInitialization(result, beanName)
    8 --> DestructionAwareBeanPostProcessor.postProcessBeforeDestruction(Object bean, String beanName)