水稻:這兩天看了BeanDefinition和BeanFactoryPostProcessor還有BeanPostProcessor的源碼。要不要了解一下java
菜瓜:six six six,大佬請講spring
水稻:上次咱們說SpringIOC容器是一個典型的工廠模式ide
菜瓜:sodasinei,BeanDefinition我瞭解了。它是建立bean的模板,相似於java建立對象依賴的class同樣。那還有兩個很長的單詞是啥呢?函數
水稻:忽略掉後面老長的後綴,咱們看BeanFactory和Bean是否是很親切。PostProcessor被翻譯成後置處理器,暫且咱們把它當作是處理器就行post
菜瓜:有了模糊的概念,不明覺厲測試
水稻:來,看demothis
package com.vip.qc.postprocessor; import org.springframework.beans.BeansException; import org.springframework.beans.MutablePropertyValues; import org.springframework.beans.factory.config.BeanDefinition; import org.springframework.beans.factory.config.BeanFactoryPostProcessor; import org.springframework.beans.factory.config.ConfigurableListableBeanFactory; import org.springframework.stereotype.Component; /** * 獲取初始化好的BeanFactory,此時還未進行bean的實例化 * * @author QuCheng on 2020/6/14. */ @Component public class BeanFactoryPostProcessorT implements BeanFactoryPostProcessor { public static final String BEAN_NAME = "processorT"; @Override public void postProcessBeanFactory(ConfigurableListableBeanFactory beanFactory) throws BeansException { BeanDefinition initializingBeanT = beanFactory.getBeanDefinition(BEAN_NAME); MutablePropertyValues propertyValues = initializingBeanT.getPropertyValues(); String pName = "a"; System.out.println("BeanFactoryPostProcessor a " + propertyValues.getPropertyValue(pName) + " -> 1"); propertyValues.addPropertyValue(pName, "1"); } } package com.vip.qc.postprocessor; import org.springframework.beans.BeansException; import org.springframework.beans.factory.config.BeanPostProcessor; import org.springframework.stereotype.Component; /** * @author QuCheng on 2020/6/14. */ @Component public class BeanPostProcessorT implements BeanPostProcessor { public static final String beanNameT = "processorT"; @Override public Object postProcessBeforeInitialization(Object bean, String beanName) throws BeansException { if (beanNameT.equals(beanName)) { ProcessorT processorT = ((ProcessorT) bean); System.out.println("BeanPostProcessor BeforeInitialization a:" + processorT.getA() + "-> 3"); processorT.setA("3"); } return bean; } @Override public Object postProcessAfterInitialization(Object bean, String beanName) throws BeansException { if (beanNameT.equals(beanName)){ ProcessorT processorT = ((ProcessorT) bean); System.out.println("BeanPostProcessor AfterInitialization a:" + processorT.getA() + "-> 4"); processorT.setA("4"); } return bean; } } package com.vip.qc.postprocessor; import org.springframework.stereotype.Component; /** * @author QuCheng on 2020/6/14. */ @Component public class ProcessorT { public ProcessorT() { System.out.println("ProcessorT 無參構造 a:" + a + "-> 2" ); a = "2"; } private String a; public String getA() { return a; } public void setA(String a) { this.a = a; } @Override public String toString() { return "ProcessorT{" + "a='" + a + '\'' + '}'; } } // 測試類 @Test public void test() { AnnotationConfigApplicationContext context = new AnnotationConfigApplicationContext("com.vip.qc.postprocessor"); ProcessorT processorT = (ProcessorT) context.getBean("processorT"); System.out.println(processorT); } // 結果 BeanFactoryPostProcessor a null -> 1 ProcessorT 無參構造 a:null-> 2 BeanPostProcessor BeforeInitialization a:1-> 3 BeanPostProcessor AfterInitialization a:3-> 4 ProcessorT{a='4'}
BeanFactoryPostProcessor在對象還未初始化前能夠拿到對象的BeanDefinition對其設置屬性值 spa
菜瓜:好像看懂了。BeanFactoryPostProcessor能夠拿到BeanFactory對象,獲取裏面全部的BeanDefinition並可對其進行干預。BeanPostProcessor實際上是在bean已經被建立完成以後進行加工操做翻譯
水稻:沒錯。這是咱們本身進行干預的demo。限於篇幅有限,你能夠去看一下Spring本身對於這兩個接口的實現源碼。比較重要的推薦下面幾個code
菜瓜:你放心,我不會看的。這麼複雜的東西,聽着都費勁
水稻:不愧是你!沒事,有機會聊bean的生命週期的時候我們還會說到這些東西。到時候再刷一遍