水稻:这两天看了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的生命周期的时候我们还会说到这些东西。到时候再刷一遍