自定义BeanFactoryPostProcessor的错误做法
BeanFactoryPostProcessor 介绍
Spring提供了很多个扩展点,包括BeanFactoryPostProcessor、BeanPostProcessor、Aware,今天主要讲述下 BeanFactoryPostProcessor 的功能及错误用法。
BeanFactoryPostProcessor 能做什么?先贴下源代码。
1 | package org.springframework.beans.factory.config; |
比较重要的内容是两段话是:
- 这是 BeanFactory 钩子,允许对应用程序上下文的bean定义进行自定义修改,从而调整上下文底层bean工厂的bean属性值。
- 可以与bean定义交互并修改bean定义,但决不能与bean实例交互。这样做可能会导致意外的副作用。如果需要和bean实例交互,请考虑实现 BeanPostProcessor。
下面那段话的意思是说,你可以hack修改bean的定义,但你不能在这个地方触发 bean 的实例化,否则可能会有无法意料的作用。所以,绝对不允许在 BeanFactoryPostProcessor 中触发 bean 的实例化。在这个阶段, bean 还没有实例化,之后会根据 bean 的定义来实例化,在这阶段你添加不了新的 bean 定义,但可以修改 bean 的定义,不能提前实例化 bean,也因为可能还要其他 BeanFactoryPostProcessor 需要修改这个bean 的定义。
一种提前实例化导致的错误
在实例化 bean 的时候,会为每个 bean 调用每一个的 BeanPostProcessor 实现类。在spring 的启动流程中,是先实例化并执行所有的 BeanFactoryPostProcessor, 然后再向容器中注册 BeanPostProcessor。 假如我在 BeanFactoryPostProcessor 实例化了 bean,会导致此时有一些 BeanPostProcessor 还未注册,所以一些 BeanPostProcessor 将无法执行到,比如 CommonAnnotationBeanPostProcessor,这个处理器用于处理 @PostConstruct 注解,用来初始化 bean,如果你在 BeanFactoryPostProcessor 中一不小心实例化了这个bean,那么 @PostConstruct 修饰的方法将不会执行。
同理,@Autowired 等注解也将失效。