Spring 中的 BeanPostProcessor接口
BeanPostProcessor接口的作用是在Spring完成实例化之后,对Spring容器实例化的Bean添加一些自定义的处理逻辑。
BeanPostProcessor的作用域是容器级的,它只和所在容器有关。如果你在容器中定义了BeanPostProcessor,它仅仅对此容器中的bean进行处理。它不会对定义在另一个容器中的bean进行任何处理。
BeanPostProcessor 接口提供了两个方法,你可以实现这两个方法来提供自己的实例化逻辑,依赖解析逻辑等。你也可以在 Spring 容器通过插入一个或多个 BeanPostProcessor 的实现,来完成在初始化一个bean的之前和之后实现一些自定义逻辑。
你可以配置多个 BeanPostProcessor接口,通过在实现 BeanPostProcessor 接口时同时实现的 Ordered 接口提供的 getOrder 方法来控制这些 BeanPostProcessor 接口的执行顺序。如果没有实现Ordered接口,则先注册的BeanPostProcessor 会先被执行。具体执行顺序如下:
BeanPostProcessor1.postProcessBeforeInitialization
BeanPostProcessor2.postProcessBeforeInitialization
BeanPostProcessor3.postProcessBeforeInitialization
BeanPostProcessor1.postProcessAfterInitialization
BeanPostProcessor2.postProcessAfterInitialization
BeanPostProcessor3.postProcessAfterInitialization
postProcessBeforeInitialization
postProcessBeforeInitialization 方法会在Bean构造完成后(构造方法执行完成),初始化方法(init-method)方法调用之前被调用。postProcessBeforeInitialization方法接收两个参数:
- Object bean: 刚刚由Spring实例化出来的Bean
- String beanName,在Spring配置元数据中Bean的名称(id or name)。
postProcessBeforeInitialization方法的返回值会被Spring容器作为处理后的Bean注册到容器中。如果你在postProcessBeforeInitialization方法中重新构造了一个Bean进行返回,而不是返回参数中的bean;那么你返回的Bean将会被注册到Spring容器中。而原来在Spring中配置的Bean(被Spring实例化的Bean)将会被覆盖。
postProcessAfterInitialization 方法会在Bean的初始化方法(init-method)被容器调用之后执行。postProcessBeforeInitialization方法与postProcessBeforeInitialization方法一样接收两个参数:
- Object bean: 刚刚由Spring容器调用过初始化方法(init-method)的Bean;
- String beanName,在Spring配置元数据中Bean的名称(id or name)。
postProcessAfterInitialization 方法的返回值会被Spring容器作为处理后的Bean注册到容器中。如果你在postProcessAfterInitialization 方法中重新构造了一个Bean进行返回,而不是返回参数中的bean;那么你返回的Bean将会被注册到Spring容器中。而原来在Spring中配置的Bean(被Spring实例化的Bean)将会被覆盖。
注意:
BeanFactory和ApplicationContext对待BeanPostProcessor接口稍有不同。ApplicationContext会自动检测在配置文件中实现了BeanPostProcessor接口的所有bean,并把它们注册为后置处理器,然后在容器创建bean的适当时候调用它。部署一个后置处理器同部署其他的bean并没有什么区别。而使用BeanFactory实现的时候,bean 后置处理器必须通过下面类似的代码显式地去注册,代码如下:
BeanPostPrcessorImpl beanPostProcessor = new BeanPostPrcessorImpl();
Resource resource = new ClassPathResource("beans.xml");
ConfigurableBeanFactory factory = new XmlBeanFactory(resource);
factory.addBeanPostProcessor(beanPostProcessor);
BeanPostProcessor 接口实现Bean的注册方式
<bean class="com.tutorialspoint.InitHelloWorld" />
因为不会在其他地方使用,所以可以不指定Bean的名字和id。