0x01 描述

  1. Bean后置处理器允许在Bean的创建过程中做出相应的调整(回调相应的后置处理器)
  2. 从而使Bean成为符合我们需求的Bean
  3. 注:
  4. ApplicationContext会自动检测由BeanPostProcessor接口的实现定义的Bean
  5. 注册这些Bean为后置处理器,然后通过在容器中创建Bean,在适当的时候调用它

0x02 Bean加载过程图

  1. 可以大致看一下,这样可以更好的理解后置处理器
  2. 注: 有错的话,可以联系我进行修改

Spring Bean加载过程.xmind
Spring Bean加载过程.png

0x03 Bean后置处理器

0x03.1 BeanPostProcessor

  1. BeanPostProcessor:
  2. 就是帮助我们在bean实例化之后,初始化前后做一些事情
  1. 类继承BeanPostProcessor以后会出现如下方法可供使用:
  2. postProcessBeforeInitialization:
  3. 初始化之前执行,该方法的返回值类型是Object
  4. postProcessAfterInitialization:
  5. 初始化完毕时执行,该方法的返回值类型是Object

0x03.2 InstantiationAwareBeanPostProcessor

  1. InstantiationAwareBeanPostProcessor接口继承BeanPostProcessor接口
  2. 在于目标对象的实例化过程中需要处理的事情,包括实例化对象的前后过程以及实例的属性设置
  1. 类继承InstantiationAwareBeanPostProcessor以后会出现如下方法可供使用:
  2. postProcessBeforeInstantiation():
  3. 在目标对象实例化之前调用,该方法的返回值类型是Object
  4. 由于这个时候目标对象还未被实例化,所以这个返回值可以用来代替原本该生成的目标对象的实例
  5. 注: 如果该方法的返回值代替原本该生成的目标对象,后续只有postProcessorAfterIniaialization方法会调用,其他方法不再调用
  6. postProcessAfterInstantiation():
  7. 在目标对象实例化之后调用,该方法的返回值类型是boolean
  8. 这个时候对象已经被实例化,但是该实例的属性还未被设置,都是null
  9. 注一: 不管postProcessBeforeInstantiation()返回什么都会执行
  10. 注二: 如果该方法的返回值是false,会忽略postProcessProperties()与postProcessPropertyValues()方法的执行
  11. postProcessProperties():
  12. 对属性值进行修改,该方法的返回值类型是PropertyValues
  13. 这个时候属性值还未被设置,但是我们可以修改原本该设置进去的属性值
  14. 注: 如果postProcessAfterInstantiation()返回false, 该方法不会被调用
  15. postProcessPropertyValues():
  16. 对属性值进行修改,该方法的返回值类型是PropertyValues
  17. 这个时候属性值还未被设置,但是我们可以修改原本该设置进去的属性值
  18. 对比postProcessProperties()方法多了个PropertyDescriptor[]参数
  19. 注: 如果postProcessAfterInstantiation()返回false, 该方法不会被调用
  20. 注二: 如果执行了postProcessProperties(),那么本方法就不会被执行

0x03.3 MergedBeanDefinitionPostProcessor

  1. MergedBeanDefinitionPostProcessor接口继承BeanPostProcessor接口
  2. 它是一个用于合并BeanDefinition的后置处理器
  3. 一般我们作为Spring的用户来说不会用到它,除非有些特殊的需要
  1. 类继承MergedBeanDefinitionPostProcessor以后会出现如下方法可供使用:
  2. postProcessMergedBeanDefinition():
  3. 缓存bean注入信息的后置处理器,该方法无返回值
  4. 仅仅是缓存或者说是查询,没有完成注入

0x03.4 DestructionAwareBeanPostProcessor

  1. DestructionAwareBeanPostProcessor接口继承BeanPostProcessor接口
  2. 销毁Bean后置处理器
  1. 类继承DestructionAwareBeanPostProcessor以后会出现如下方法可供使用:
  2. requiresDestruction:
  3. 检测bean是否需要注册销毁方法,该方法的返回值类型是boolean
  4. 注: 如果该方法的返回值是false,会忽略postProcessBeforeDestruction()方法的执行
  5. postProcessBeforeDestruction:
  6. Bean销毁之前的行为处理回调方法,该回调只能应用到单例Bean,该方法无返回值
  7. 注: 如果requiresDestruction()返回false, 该方法不会被调用

0x03.5 SmartInitializingSingleton

  1. SmartInitializingSingleton接口是一个独立的接口
  2. 主要用于在IOC容器基本启动完成时进行扩展
  3. SmartInitializingSingleton是所有的非延迟的、单例的bean都初始化后调用,只调用一次
  4. 如果是多例的bean实现,不会调用
  1. 类继承SmartInitializingSingleton以后会出现如下方法可供使用:
  2. afterSingletonsInstantiated():
  3. 当所有单例bean都初始化完成以后,容器会回调该接口的方法
  4. 主要应用场合就是在所有单例bean创建完成之后,可以在该回调中做一些事情

0x03.6 SmartInstantiationAwareBeanPostProcessor

  1. SmartInstantiationAwareBeanPostProcessor接口继承InstantiationAwareBeanPostProcessor接口
  2. 智能实例化Bean后置处理器
  1. 类继承SmartInstantiationAwareBeanPostProcessor以后会出现如下方法可供使用:
  2. predictBeanType():
  3. 预测bean的类型,该方法的返回值类型是Class<?>
  4. determineCandidateConstructors():
  5. 监测Bean的构造器,该方法的返回值类型是Constructor<?>[]
  6. getEarlyBeanReference():
  7. 循环引用的后置处理器,该方法的返回值类型是Object
  8. 这个比较复杂,获取提前暴露的bean引用
  9. 主要用于解决循环引用的问题,并且只有单例对象才会调用此方法(一般是bean自身,如果是代理对象则需要取用代理引用)

0x04 前置操作

  1. // 在./SpringDemo/src/main/java/com/test/创建个HelloWorld.java
  2. // 目录: ./SpringDemo/src/main/java/com/test/
  3. // 文件名: HelloWorld3.java
  4. package com.test;
  5. public class HelloWorld3 {
  6. private String message;
  7. public void setMessage(String message) {
  8. this.message = message;
  9. }
  10. public void getMessage() {
  11. System.out.println("Your Message: " + message);
  12. }
  13. public void init() {
  14. System.out.println("这个bean进行了初始化");
  15. }
  16. public void destroy() {
  17. System.out.println("这个bean被销毁了");
  18. }
  19. }
  1. // 在./SpringDemo/src/main/resources/创建个applicationContext2.xml
  2. // 目录: ./SpringDemo/src/main/resources/
  3. // 文件名: applicationContext2.xml
  4. <?xml version="1.0" encoding="UTF-8"?>
  5. <beans xmlns="http://www.springframework.org/schema/beans"
  6. xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
  7. xsi:schemaLocation="http://www.springframework.org/schema/beans
  8. https://www.springframework.org/schema/beans/spring-beans.xsd">
  9. </beans>
  1. // 在<beans>标签中,中配置HelloWorld3的信息, 设定message的值为“Hello World!”
  2. // 这里提供一个配置好的applicationContext2.xml文件
  3. // 目录: ./SpringDemo/src/main/resources/
  4. // 文件名: applicationContext2.xml
  5. <beans xmlns="http://www.springframework.org/schema/beans"
  6. xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
  7. xsi:schemaLocation="http://www.springframework.org/schema/beans
  8. https://www.springframework.org/schema/beans/spring-beans.xsd">
  9. <bean id="helloWorldTest3" class="com.test.HelloWorld3" init-method="init" destroy-method="destroy">
  10. <property name="message" value="Hello World!"/>
  11. </bean>
  12. </beans>
  1. // 创建一个测试类Test9进行测试
  2. // 目录: ./SpringDemo/src/test/java/
  3. // 文件名: Test9.java
  4. import com.test.HelloWorld3;
  5. import org.springframework.context.support.AbstractApplicationContext;
  6. import org.springframework.context.support.ClassPathXmlApplicationContext;
  7. public class Test9 {
  8. public static void main(String[] args) {
  9. AbstractApplicationContext context = new ClassPathXmlApplicationContext("applicationContext2.xml");
  10. HelloWorld3 obj = (HelloWorld3) context.getBean("helloWorldTest3");
  11. obj.getMessage();
  12. // 注册一个关闭钩子,关闭Spring IOC容器
  13. // 用来触发bean标签的destroy-method属性
  14. context.registerShutdownHook();
  15. }
  16. }

0x05 小例子

0x05.1 BeanPostProcessor

  1. // 第一步
  2. // 创建个BeanPostProcessor后置处理器,进行测试
  3. // 目录: ./SpringDemo/src/main/java/com/test/Bean后置处理器/
  4. // 文件名: BeanPostProcessorTest.java
  5. package com.test.Bean后置处理器;
  6. import org.springframework.beans.BeansException;
  7. import org.springframework.beans.factory.config.BeanPostProcessor;
  8. public class BeanPostProcessorTest implements BeanPostProcessor {
  9. @Override
  10. public Object postProcessBeforeInitialization(Object bean, String beanName) throws BeansException {
  11. System.out.println("BeforeInitialization: " + beanName + " " + "正在执行预初始化方法");
  12. return bean;
  13. }
  14. @Override
  15. public Object postProcessAfterInitialization(Object bean, String beanName) throws BeansException {
  16. System.out.println("AfterInitialization: " + beanName + " " + "正在执行后初始化方法");
  17. return bean;
  18. }
  19. }
  1. // 第二步
  2. // 修改applicationContext2.xml引入BeanPostProcessor后置处理器
  3. // 这里提供一个配置好的applicationContext2.xml文件
  4. // 目录: ./SpringDemo/src/main/resources/
  5. // 文件名: applicationContext2.xml
  6. <?xml version="1.0" encoding="UTF-8"?>
  7. <beans xmlns="http://www.springframework.org/schema/beans"
  8. xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
  9. xsi:schemaLocation="http://www.springframework.org/schema/beans
  10. https://www.springframework.org/schema/beans/spring-beans.xsd">
  11. <bean class="com.test.Bean后置处理器.BeanPostProcessorTest"/>
  12. <bean id="helloWorldTest3" class="com.test.HelloWorld3" init-method="init" destroy-method="destroy">
  13. <property name="message" value="Hello World!"/>
  14. </bean>
  15. </beans>
  1. // 第三步
  2. // 目录: ./SpringDemo/src/test/java/
  3. // 文件名: Test9.java
  4. // 运行Test9.java
  5. // 运行结果
  6. BeforeInitialization: helloWorldTest3 正在执行预初始化方法
  7. 这个bean进行了初始化
  8. AfterInitialization: helloWorldTest3 正在执行后初始化方法
  9. Your Message: Hello World!
  10. 这个bean被销毁了

0x05.2 InstantiationAwareBeanPostProcessor

  1. // 第一步
  2. // 创建个InstantiationAwareBeanPostProcessor后置处理器,进行测试
  3. // 目录: ./SpringDemo/src/main/java/com/test/Bean后置处理器/
  4. // 文件名: InstantiationAwareBeanPostProcessorTest.java
  5. package com.test.Bean后置处理器;
  6. import org.springframework.beans.BeansException;
  7. import org.springframework.beans.PropertyValue;
  8. import org.springframework.beans.PropertyValues;
  9. import org.springframework.beans.MutablePropertyValues;
  10. import org.springframework.beans.factory.config.TypedStringValue;
  11. import org.springframework.beans.factory.config.InstantiationAwareBeanPostProcessor;
  12. import java.beans.PropertyDescriptor;
  13. public class InstantiationAwareBeanPostProcessorTest implements InstantiationAwareBeanPostProcessor {
  14. @Override
  15. public Object postProcessBeforeInstantiation(Class<?> beanClass, String beanName) throws BeansException {
  16. System.out.println("postProcessBeforeInstantiation: " + beanName + " ");
  17. return null;
  18. }
  19. @Override
  20. public boolean postProcessAfterInstantiation(Object bean, String beanName) throws BeansException {
  21. // 注: 如果该方法的返回值是false,会忽略postProcessProperties与postProcessPropertyValues()方法的执行
  22. System.out.println("postProcessAfterInstantiation: " + beanName + " ");
  23. return true;
  24. }
  25. @Override
  26. public PropertyValues postProcessProperties(PropertyValues pvs, Object bean, String beanName) throws BeansException {
  27. if (beanName.equals("helloWorldTest3")) {
  28. // 获取bean名为helloWorldTest3的message属性数据
  29. PropertyValue pv = pvs.getPropertyValue("message");
  30. TypedStringValue obj = (TypedStringValue) pv.getValue();
  31. // 修改message属性数据
  32. // 固定在message属性值的最后面添加一句: 属性值修改测试
  33. MutablePropertyValues p = new MutablePropertyValues();
  34. p.add("message", obj.getValue() + " " + "属性值修改测试-postProcessProperties");
  35. return p;
  36. } else {
  37. return pvs;
  38. }
  39. }
  40. @Override
  41. public PropertyValues postProcessPropertyValues(PropertyValues pvs, PropertyDescriptor[] pds, Object bean, String beanName) throws BeansException {
  42. System.out.println("postProcessPropertyValues: " + beanName + " ");
  43. if (beanName.equals("helloWorldTest3")) {
  44. // 获取bean名为helloWorldTest3的message属性数据
  45. PropertyValue pv = pvs.getPropertyValue("message");
  46. TypedStringValue obj = (TypedStringValue) pv.getValue();
  47. // 修改message属性数据
  48. // 固定在message属性值的最后面添加一句: 属性值修改测试
  49. MutablePropertyValues p = new MutablePropertyValues();
  50. p.add("message", obj.getValue() + " " + "属性值修改测试-postProcessPropertyValues");
  51. return p;
  52. } else {
  53. return pvs;
  54. }
  55. }
  56. }
  1. // 第二步
  2. // 修改applicationContext2.xml引入InstantiationAwareBeanPostProcessor后置处理器
  3. // 这里提供一个配置好的applicationContext2.xml文件
  4. // 目录: ./SpringDemo/src/main/resources/
  5. // 文件名: applicationContext2.xml
  6. <?xml version="1.0" encoding="UTF-8"?>
  7. <beans xmlns="http://www.springframework.org/schema/beans"
  8. xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
  9. xsi:schemaLocation="http://www.springframework.org/schema/beans
  10. https://www.springframework.org/schema/beans/spring-beans.xsd">
  11. <bean class="com.test.Bean后置处理器.InstantiationAwareBeanPostProcessorTest"/>
  12. <bean id="helloWorldTest3" class="com.test.HelloWorld3" init-method="init" destroy-method="destroy">
  13. <property name="message" value="Hello World!"/>
  14. </bean>
  15. </beans>
  1. // 第三步
  2. // 目录: ./SpringDemo/src/test/java/
  3. // 文件名: Test9.java
  4. // 运行Test9.java
  5. // 使用了postProcessProperties()方法的运行结果
  6. postProcessBeforeInstantiation: helloWorldTest3
  7. postProcessAfterInstantiation: helloWorldTest3
  8. postProcessProperties: helloWorldTest3
  9. 这个bean进行了初始化
  10. Your Message: Hello World! 属性值修改测试-postProcessProperties
  11. 这个bean被销毁了
  12. // 注释了postProcessProperties()方法的运行结果
  13. postProcessBeforeInstantiation: helloWorldTest3
  14. postProcessAfterInstantiation: helloWorldTest3
  15. postProcessPropertyValues: helloWorldTest3
  16. 这个bean进行了初始化
  17. Your Message: Hello World! 属性值修改测试-postProcessPropertyValues
  18. 这个bean被销毁了

0x05.3 MergedBeanDefinitionPostProcessor

  1. // 第一步
  2. // 创建个MergedBeanDefinitionPostProcessor后置处理器,进行测试
  3. // 目录: ./SpringDemo/src/main/java/com/test/Bean后置处理器/
  4. // 文件名: MergedBeanDefinitionPostProcessorTest.java
  5. package com.test.Bean后置处理器;
  6. import org.springframework.beans.factory.support.MergedBeanDefinitionPostProcessor;
  7. import org.springframework.beans.factory.support.RootBeanDefinition;
  8. public class MergedBeanDefinitionPostProcessorTest implements MergedBeanDefinitionPostProcessor {
  9. @Override
  10. public void postProcessMergedBeanDefinition(RootBeanDefinition rootBeanDefinition, Class<?> aClass, String s) {
  11. System.out.println("postProcessMergedBeanDefinition: " + s);
  12. }
  13. }
  1. // 第二步
  2. // 修改applicationContext2.xml引入MergedBeanDefinitionPostProcessor后置处理器
  3. // 这里提供一个配置好的applicationContext2.xml文件
  4. // 目录: ./SpringDemo/src/main/resources/
  5. // 文件名: applicationContext2.xml
  6. <?xml version="1.0" encoding="UTF-8"?>
  7. <beans xmlns="http://www.springframework.org/schema/beans"
  8. xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
  9. xsi:schemaLocation="http://www.springframework.org/schema/beans
  10. https://www.springframework.org/schema/beans/spring-beans.xsd">
  11. <bean class="com.test.Bean后置处理器.MergedBeanDefinitionPostProcessorTest"/>
  12. <bean id="helloWorldTest3" class="com.test.HelloWorld3" init-method="init" destroy-method="destroy">
  13. <property name="message" value="Hello World!"/>
  14. </bean>
  15. </beans>
  1. // 第三步
  2. // 目录: ./SpringDemo/src/test/java/
  3. // 文件名: Test9.java
  4. // 运行Test9.java
  5. // 运行结果
  6. postProcessMergedBeanDefinition: helloWorldTest3
  7. 这个bean进行了初始化
  8. Your Message: Hello World!
  9. 这个bean被销毁了

0x05.4 DestructionAwareBeanPostProcessor

  1. // 第一步
  2. // 创建个DestructionAwareBeanPostProcessor后置处理器,进行测试
  3. // 目录: ./SpringDemo/src/main/java/com/test/Bean后置处理器/
  4. // 文件名: DestructionAwareBeanPostProcessorTest.java
  5. package com.test.Bean后置处理器;
  6. import org.springframework.beans.BeansException;
  7. import org.springframework.beans.factory.config.DestructionAwareBeanPostProcessor;
  8. public class DestructionAwareBeanPostProcessorTest implements DestructionAwareBeanPostProcessor {
  9. @Override
  10. public boolean requiresDestruction(Object bean) {
  11. // 注: 如果该方法的返回值是false,会忽略postProcessBeforeDestruction()方法的执行
  12. System.out.println("requiresDestruction: " + bean.getClass().getSimpleName() + " ");
  13. return DestructionAwareBeanPostProcessor.super.requiresDestruction(bean);
  14. }
  15. @Override
  16. public void postProcessBeforeDestruction(Object o, String s) throws BeansException {
  17. System.out.println("postProcessBeforeDestruction: " + s + " ");
  18. }
  19. }
  1. // 第二步
  2. // 修改applicationContext2.xml引入DestructionAwareBeanPostProcessor后置处理器
  3. // 这里提供一个配置好的applicationContext2.xml文件
  4. // 目录: ./SpringDemo/src/main/resources/
  5. // 文件名: applicationContext2.xml
  6. <?xml version="1.0" encoding="UTF-8"?>
  7. <beans xmlns="http://www.springframework.org/schema/beans"
  8. xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
  9. xsi:schemaLocation="http://www.springframework.org/schema/beans
  10. https://www.springframework.org/schema/beans/spring-beans.xsd">
  11. <bean class="com.test.Bean后置处理器.DestructionAwareBeanPostProcessorTest"/>
  12. <bean id="helloWorldTest3" class="com.test.HelloWorld3" init-method="init" destroy-method="destroy">
  13. <property name="message" value="Hello World!"/>
  14. </bean>
  15. </beans>
  1. // 第三步
  2. // 目录: ./SpringDemo/src/test/java/
  3. // 文件名: Test9.java
  4. // 运行Test9.java
  5. // 运行结果
  6. 这个bean进行了初始化
  7. requiresDestruction: HelloWorld3
  8. Your Message: Hello World!
  9. postProcessBeforeDestruction: helloWorldTest3
  10. 这个bean被销毁了

0x05.5 SmartInitializingSingleton

  1. // 第一步
  2. // 创建个SmartInitializingSingleton后置处理器,进行测试
  3. // 目录: ./SpringDemo/src/main/java/com/test/Bean后置处理器/
  4. // 文件名: SmartInitializingSingletonTest.java
  5. package com.test.Bean后置处理器;
  6. import org.springframework.beans.factory.SmartInitializingSingleton;
  7. public class SmartInitializingSingletonTest implements SmartInitializingSingleton {
  8. @Override
  9. public void afterSingletonsInstantiated() {
  10. System.out.println("SmartInitializingSingleton后置处理器的afterSingletonsInstantiated()方法被执行了");
  11. }
  12. }
  1. // 第二步
  2. // 修改applicationContext2.xml引入SmartInitializingSingleton后置处理器
  3. // 这里提供一个配置好的applicationContext2.xml文件
  4. // 目录: ./SpringDemo/src/main/resources/
  5. // 文件名: applicationContext2.xml
  6. <?xml version="1.0" encoding="UTF-8"?>
  7. <beans xmlns="http://www.springframework.org/schema/beans"
  8. xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
  9. xsi:schemaLocation="http://www.springframework.org/schema/beans
  10. https://www.springframework.org/schema/beans/spring-beans.xsd">
  11. <bean class="com.test.Bean后置处理器.SmartInitializingSingletonTest"/>
  12. <bean id="helloWorldTest3" class="com.test.HelloWorld3" init-method="init" destroy-method="destroy">
  13. <property name="message" value="Hello World!"/>
  14. </bean>
  15. </beans>
  1. // 第三步
  2. // 目录: ./SpringDemo/src/test/java/
  3. // 文件名: Test9.java
  4. // 运行Test9.java
  5. // 运行结果
  6. 这个bean进行了初始化
  7. SmartInitializingSingleton后置处理器的afterSingletonsInstantiated()方法被执行了
  8. Your Message: Hello World!
  9. 这个bean被销毁了

0x05.6 SmartInstantiationAwareBeanPostProcessor

  1. getEarlyBeanReference()方法的触发,比较复杂,获取提前暴露的bean引用
  2. 主要用于解决循环引用的问题,并且只有单例对象才会调用此方法
  3. 因此这里整一个拥有循环引用问题的代码
  4. 来触发SmartInstantiationAwareBeanPostProcessorgetEarlyBeanReference()方法
  1. // 第一步
  2. // 创建个SmartInstantiationAwareBeanPostProcessor后置处理器,进行测试
  3. // 目录: ./SpringDemo/src/main/java/com/test/Bean后置处理器/
  4. // 文件名: SmartInstantiationAwareBeanPostProcessorTest.java
  5. package com.test.Bean后置处理器;
  6. import org.springframework.beans.BeansException;
  7. import org.springframework.beans.factory.config.SmartInstantiationAwareBeanPostProcessor;
  8. import java.lang.reflect.Constructor;
  9. public class SmartInstantiationAwareBeanPostProcessorTest implements SmartInstantiationAwareBeanPostProcessor {
  10. @Override
  11. public Class<?> predictBeanType(Class<?> beanClass, String beanName) throws BeansException {
  12. System.out.println("predictBeanType: " + beanName);
  13. return beanClass;
  14. }
  15. @Override
  16. public Constructor<?>[] determineCandidateConstructors(Class<?> beanClass, String beanName) throws BeansException {
  17. System.out.println("determineCandidateConstructors: " + beanName);
  18. return null;
  19. }
  20. @Override
  21. public Object getEarlyBeanReference(Object bean, String beanName) throws BeansException {
  22. System.out.println("getEarlyBeanReference: " + beanName);
  23. return bean;
  24. }
  25. }
  1. // 第二步
  2. // 创建个拥有循环依赖的代码,进行测试
  3. // 目录: ./SpringDemo/src/main/java/com/test/循环依赖/
  4. // 文件名: ServiceA.java
  5. package com.test.循环依赖;
  6. public class ServiceA {
  7. private ServiceB serviceB;
  8. public void setServiceB(ServiceB serviceB) {
  9. this.serviceB = serviceB;
  10. }
  11. public ServiceB getServiceB() {
  12. return serviceB;
  13. }
  14. }
  15. // 文件名: ServiceB.java
  16. package com.test.循环依赖;
  17. public class ServiceB {
  18. private ServiceA serviceA;
  19. public void setServiceA(ServiceA serviceA) {
  20. this.serviceA = serviceA;
  21. }
  22. public ServiceA getServiceA() {
  23. return serviceA;
  24. }
  25. }
  1. // 第三步
  2. // 创建个applicationContext3.xml引入SmartInstantiationAwareBeanPostProcessor后置处理器
  3. // 这里提供一个配置好的applicationContext3.xml文件
  4. // 目录: ./SpringDemo/src/main/resources/
  5. // 文件名: applicationContext3.xml
  6. <?xml version="1.0" encoding="UTF-8"?>
  7. <beans xmlns="http://www.springframework.org/schema/beans"
  8. xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
  9. xsi:schemaLocation="http://www.springframework.org/schema/beans
  10. https://www.springframework.org/schema/beans/spring-beans.xsd">
  11. <bean class="com.test.Bean后置处理器.SmartInstantiationAwareBeanPostProcessorTest"/>
  12. <bean id="serviceATest" class="com.test.循环依赖.ServiceA">
  13. <property name="serviceB" ref="serviceBTest"/>
  14. </bean>
  15. <bean id="serviceBTest" class="com.test.循环依赖.ServiceB">
  16. <property name="serviceA" ref="serviceATest"/>
  17. </bean>
  18. </beans>
  1. // 第四步
  2. // 创建一个测试类Test10进行测试
  3. // 目录: ./SpringDemo/src/test/java/
  4. // 文件名: Test10.java
  5. import org.springframework.context.support.AbstractApplicationContext;
  6. import org.springframework.context.support.ClassPathXmlApplicationContext;
  7. public class Test10 {
  8. public static void main(String[] args) {
  9. AbstractApplicationContext context = new ClassPathXmlApplicationContext("applicationContext3.xml");
  10. context.getBean("serviceATest");
  11. }
  12. }
  13. // 运行结果
  14. predictBeanType: serviceATest
  15. predictBeanType: serviceBTest
  16. predictBeanType: serviceATest
  17. predictBeanType: serviceBTest
  18. determineCandidateConstructors: serviceATest
  19. determineCandidateConstructors: serviceBTest
  20. getEarlyBeanReference: serviceATest