最近研究Spring bean的后置处理BeanFactoryPostProcessor和BeanPostProcessor,这两个接口都是spring初始化bean时对外暴露的扩展点。
1、BeanFactoryPostProcessor接口
package org.springframework.beans.factory.config; import org.springframework.beans.BeansException; public interface BeanFactoryPostProcessor { void postProcessBeanFactory(ConfigurableListableBeanFactory var1) throws BeansException; }
此接口只有一个方法,可以在spring创建bean之前,系应该bean定义的属性。注意,BeanFactoryPostProcessor是在spring加载完成bean定义之后,实例化bean之前执行的,ConfigurrableListableBeanFactory可以获取所有bean的定义信息。
public class MyBeanFactoryPostProcessor implements BeanFactoryPostProcessor { @Override public void postProcessBeanFactory(ConfigurableListableBeanFactory beanFactory) throws BeansException { // 现获取bean定义 BeanDefinition bd = beanFactory.getBeanDefinition("testBean"); // 修改bean的属性 MutablePropertyValues mpv = bd.getPropertyValues(); if(mpv.contains("remark")){ mpv.addPropertyValue("remark","dgfjf"); } } }
2、BeanPostProcessor接口
package org.springframework.beans.factory.config; import org.springframework.beans.BeansException; public interface BeanPostProcessor { Object postProcessBeforeInitialization(Object var1, String var2) throws BeansException; Object postProcessAfterInitialization(Object var1, String var2) throws BeansException; }BeanPostProcessor实在Spring加载了bean定义并且实例化bean之后,在执行bean的初始化方法前后,添加一些自己的处理逻辑。这里说的初始化方法,指的是下面两种:
1)bean实现了InitializingBean接口,对应的方法为afterPropertiesSet
2)在bean定义的时候,通过init-method设置的方法
public class MyBeanPostProcessor implements BeanPostProcessor { @Override public Object postProcessBeforeInitialization(Object bean, String beanName) throws BeansException { System.out.println("在执行初始化方法之前"); return bean; } @Override public Object postProcessAfterInitialization(Object bean, String beanName) throws BeansException { System.out.println("早执行初始化方法之后"); return bean; } }
3、使用BeanFactoryPostProcessor需要注意的问题
Special consideration must be taken for @Bean
methods that return SpringBeanFactoryPostProcessor
(BFPP
) types. Because BFPP
objects must be instantiated very early in thecontainer lifecycle, they can interfere with processing of annotations such as@Autowired
,@Value
, and @PostConstruct
within@Configuration
classes. To avoid theselifecycle issues, mark BFPP
-returning@Bean
methods as static
. For example:
@Bean public static PropertyPlaceholderConfigurer ppc() { // instantiate, configure and return ppc ... }即当配置时用BeanFactoryPostProcessor的时候,最好的方式是加上static,因为有可能在注入其属性的时候,BeanPostProcessor可能还没有被注册,导致注入失败。
4、在使用ApplicationContext启动spring容器的时候,在AbstractApplicationContext.refresh()方法中,完成相关初始化工作:
此文章参考blog:https://blog.csdn.net/abw986810159/article/details/61196972