主要工作

上面三个过程,都是在做准备工作,接下来的工作就是要开始干活了。
首先就给用户一个扩展点,AbstractApplicationContext # postProcessBeanFactory(beanFactory)

  1. try {
  2. // Allows post-processing of the bean factory in context subclasses.
  3. postProcessBeanFactory(beanFactory);
  4. ......
  5. }
  6. ......
  7. protected void postProcessBeanFactory(ConfigurableListableBeanFactory beanFactory) {
  8. }

IOC容器当前的状态:所有的 bean 定义都已经加载完毕,并且都放在缓存中了。但是还没有进行实例化操作。

扩展:

  1. 通过 postProcessBeanFactory 方法可以实现对 BeanDefinition 数据的操作。
  2. 除此之外可以通过 BeanFactoryPostProcessor 扩展对 BeanDefinition 操作,多个可以通过 Ordered、PriorityOrdered 接口进行排序。

    代码演示

    重写方法

    首先我们先重写 postProcessBeanFactory 方法演示:

    1. /**
    2. * 自定义ApplicationContext
    3. */
    4. public class MyApplicationContext2 extends ClassPathXmlApplicationContext {
    5. public MyApplicationContext2(String configLocation) throws BeansException {
    6. super(configLocation);
    7. }
    8. @Override
    9. protected void postProcessBeanFactory(ConfigurableListableBeanFactory beanFactory) {
    10. int beanDefinitionCount = beanFactory.getBeanDefinitionCount();
    11. System.out.println("beanDefinitionCount:" + beanDefinitionCount);
    12. }
    13. }

加载bean配置文件,bean2.xml

  1. <?xml version="1.0" encoding="UTF-8"?>
  2. <!DOCTYPE beans PUBLIC "-//SPRING//DTD BEAN 2.0//EN"
  3. "https://www.springframework.org/dtd/spring-beans-2.0.dtd">
  4. <beans>
  5. <bean id="user" class="cn.lichenghao.entity.User">
  6. <property name="name">
  7. <value>Rod</value>
  8. </property>
  9. <property name="age">
  10. <value>31</value>
  11. </property>
  12. </bean>
  13. </beans>

测试下

  1. /**
  2. * 测试扩展
  3. *
  4. * @author chenghao.li
  5. */
  6. public class App4 {
  7. public static void main(String[] args) {
  8. MyApplicationContext2 myApplicationContext = new MyApplicationContext2("bean2.xml");
  9. User user = myApplicationContext.getBean(User.class);
  10. user.sayHello();
  11. }
  12. }

结果

  1. 结果:
  2. > Task :spring-lich-test:App4.main()
  3. beanDefinitionCount2
  4. hello world!

接口扩展

我们使用扩展点接口,分别打印加载的 bean 定义的个数:

  1. /**
  2. * 自定义扩展
  3. *
  4. * @author chenghao.li
  5. */
  6. public class MyBeanFactoryPostProcessor implements BeanFactoryPostProcessor, Ordered {
  7. @Override
  8. public void postProcessBeanFactory(ConfigurableListableBeanFactory beanFactory)
  9. throws BeansException {
  10. int beanDefinitionCount = beanFactory.getBeanDefinitionCount();
  11. System.out.println("MyBeanFactoryPostProcessor beanDefinitionCount:" + beanDefinitionCount);
  12. }
  13. @Override
  14. public int getOrder() {
  15. return 0;
  16. }
  17. }
  1. /**
  2. * 自定义扩展
  3. *
  4. * @author chenghao.li
  5. */
  6. public class MyBeanFactoryPostProcessor2 implements BeanFactoryPostProcessor, PriorityOrdered {
  7. @Override
  8. public void postProcessBeanFactory(ConfigurableListableBeanFactory beanFactory)
  9. throws BeansException {
  10. int beanDefinitionCount = beanFactory.getBeanDefinitionCount();
  11. System.out.println("MyBeanFactoryPostProcessor2 beanDefinitionCount:" + beanDefinitionCount);
  12. }
  13. @Override
  14. public int getOrder() {
  15. return 1;
  16. }
  17. }

bean.xml

  1. <?xml version="1.0" encoding="UTF-8"?>
  2. <!DOCTYPE beans PUBLIC "-//SPRING//DTD BEAN 2.0//EN"
  3. "https://www.springframework.org/dtd/spring-beans-2.0.dtd">
  4. <beans>
  5. <bean id="user" class="cn.lichenghao.entity.User">
  6. <property name="name">
  7. <value>Rod</value>
  8. </property>
  9. <property name="age">
  10. <value>31</value>
  11. </property>
  12. </bean>
  13. <bean id="myBeanFactoryPostProcessor" class="cn.lichenghao.context.MyBeanFactoryPostProcessor"/>
  14. <bean id="myBeanFactoryPostProcessor2" class="cn.lichenghao.context.MyBeanFactoryPostProcessor2"/>
  15. </beans>

测试下

  1. /**
  2. * 测试扩展
  3. *
  4. * @author chenghao.li
  5. */
  6. public class App4 {
  7. public static void main(String[] args) {
  8. MyApplicationContext2 myApplicationContext = new MyApplicationContext2("bean2.xml");
  9. User user = myApplicationContext.getBean(User.class);
  10. user.sayHello();
  11. }
  12. }

测试结果

  1. > Task :spring-lich-test:App4.main()
  2. beanDefinitionCount3
  3. MyBeanFactoryPostProcessor beanDefinitionCount:3
  4. MyBeanFactoryPostProcessor2 beanDefinitionCount:3
  5. hello world!

注意事项

  1. 这个阶段让用户注册自己的扩展取操作 bean 的定义数据,不要在这个阶段去实例化 bean。
  2. 通过接口 (BeanFactoryPostProcessor) 注册的扩展,会在下个阶段 (invokeBeanFactoryPostProcessors) 进行调用。