1. BeanPostProcessor
1.1 doc
文档说明:
- 官网 doc
- api doc
Factory hook that allows for custom modification of new bean instances — for example, checking for marker interfaces or wrapping beans with proxies. Typically, post-processors that populate beans via marker interfaces or the like will implement postProcessBeforeInitialization(java.lang.Object, java.lang.String), while post-processors that wrap beans with proxies will normally implement postProcessAfterInitialization(java.lang.Object, java.lang.String).
描述实在太长了,这里就不贴了,大家自己去上面可以阅读下哈。
下面概述总结下:
BeanPostProcessor 是一个容器的扩展点,它可以在 bean 的生命周期过程中,初始化阶段前后添加自定义处理逻辑,并且不同 IOC 容器间的 BeanPostProcessor 不会相互干预。
1.2 使用
@Component
public class TestBeanPostProcessor implements BeanPostProcessor {
@Override
public Object postProcessBeforeInitialization(Object bean, String beanName) throws BeansException {
System.out.println("拦截到Bean的初始化之前:" + beanName);
return bean;
}
@Override
public Object postProcessAfterInitialization(Object bean, String beanName) throws BeansException {
System.out.println("拦截到Bean的初始化之后:" + beanName);
return bean;
}
}
- 如果 return null 也能正常返回,是因为 Spring BeanPostProcessor 的 postProcessBeforeInitialization 方法,是在 AbstractAutowireCapableBeanFactory 中被调用的,而其中有一层兜底策略。如果返回 null,仍会返回。
大家可以运行下,可以得出和前面学过的例如 init 方法等的顺序:BeanPostProcessor#postProcessBeforeInitialization → @PostConstruct → InitializingBean → init-method → BeanPostProcessor#postProcessAfterInitialization
- 就是下面这份代码 + 上面的 BeanPostProcessor
这个顺序问题,后面到 Bean 的生命周期我们再细细看。
public class Test implements InitializingBean {
public void initMethod() {
System.out.println("initMethod ...");
}
@PostConstruct
public void postConstruct() {
System.out.println("PostConstruct ...");
}
@Override
public void afterPropertiesSet() throws Exception {
System.out.println("InitializingBean ...");
}
}
2. 扩展
2.1 InstantiationAwareBeanPostProcessor
方法:
postProcessBeforeInstantiation :在 bean 的实例化之前处理非常容易理解,它可以拦截 bean 原本的实例化方法,转为用这里的实例化
- postProcessAfterInstantiation :在 bean 的实例化之后处理,如果返回 false ,则 postProcessProperties 方法不会执行
- postProcessProperties :最终会返回一组属性和值的 PropertyValues ,让它参与 bean 的属性赋值环节
如果说我们刚才的执行顺序是这样的
① xxx -> ② Bean 实例化 -> ③ 属性赋值、自检自动注入 -> ④ 初始化方法回调(@PostConstruct 、InitializingBean、initMethod)-> ⑤ 完毕
BeanPostProcessor 的 postProcessBeforeInitialization 和 postProcessAfterInitialization 方法是在 ④ 和 ⑤ 之间,那么 InstantiationAwareBeanPostProcessor 的 postProcessBeforeInstantiation 就是在 ① 和 ② 之间,而 postProcessAfterInstantiation 和 postProcessProperties (postProcessPropertyValues) 就是在 ② 和 ③ 之间,其实就是在 ② Bean 实例化 前后执行。
3. BeanFactoryPostProcessor
3.1 概述和使用
BeanFactoryPostProcessor 是容器的扩展点,它用于 IOC 容器的生命周期中,所有 BeanDefinition 都注册到 BeanFactory 后回调触发,用于访问 / 修改已经存在的 BeanDefinition 。与 BeanPostProcessor 相同,它们都是容器隔离的,不同容器中的 BeanFactoryPostProcessor 不会相互起作用。
public void postProcessBeanFactory(ConfigurableListableBeanFactory beanFactory) throws BeansException {
Stream.of(beanFactory.getBeanDefinitionNames()).forEach(beanName -> {
BeanDefinition beanDefinition = beanFactory.getBeanDefinition(beanName);
if (StringUtils.hasText(beanDefinition.getBeanClassName())) {
if (ClassUtils.resolveClassName(beanDefinition.getBeanClassName(), this.getClass().getClassLoader())
.getSuperclass().equals(Color.class)) {
beanDefinition.getPropertyValues().add("name", beanName);
}
}
});
}
3.2 BeanPostProcessor 和 BeanFactoryPostProcessor 的区别:
BeanPostProcessor | BeanFactoryPostProcessor | |
---|---|---|
处理目标 | bean 实例 | BeanDefinition |
执行时机 | bean 的初始化阶段前后(已创建出 bean 对象) | BeanDefinition 解析完毕,注册进 BeanFactory 的阶段( bean 未实例化) |
可操作的空间 | 给 bean 的属性赋值、创建代理对象等 | 给 BeanDefinition 中增删属性、移除 BeanDefinition |
4. BeanDefinitionRegistryPostProcessor
BeanDefinitionRegistryPostProcessor 是容器的扩展点,它用于 IOC 容器的生命周期中,所有 BeanDefinition 都准备好,即将加载到 BeanFactory 时回调触发,用于给 BeanFactory 中添加新的 BeanDefinition 。BeanDefinitionRegistryPostProcessor 也是容器隔离的,不同容器中的 BeanDefinitionRegistryPostProcessor 不会相互起作用。
@Component
public class TestRegisterPostProcessor implements BeanDefinitionRegistryPostProcessor {
@Override
public void postProcessBeanDefinitionRegistry(BeanDefinitionRegistry registry) throws BeansException {
if (!registry.containsBeanDefinition("dog")) {
// 构造BeanDefinition,并注册进BeanFactory
BeanDefinition dogDefinition = BeanDefinitionBuilder.genericBeanDefinition(Dog.class).getBeanDefinition();
registry.registerBeanDefinition("dog", dogDefinition);
}
}
@Override
public void postProcessBeanFactory(ConfigurableListableBeanFactory beanFactory) throws BeansException {
}
}
5. 三者的区别
BeanPostProcessor | BeanFactoryPostProcessor | BeanDefinitionRegistryPostProcessor | |
---|---|---|---|
处理目标 | bean 实例 | BeanDefinition |
BeanDefinition 、 .class 文件等 |
执行时机 | bean 的初始化阶段前后(已创建出 bean 对象) | BeanDefinition 解析完毕并注册进 BeanFactory 之后(此时 bean 未实例化) |
配置文件、配置类已解析完毕并注册进 BeanFactory ,但还没有被 BeanFactoryPostProcessor 处理 |
可操作的空间 | 给 bean 的属性赋值、创建代理对象等 | 给 BeanDefinition 中增删属性、移除 BeanDefinition 等 |
向 BeanFactory 中注册新的 BeanDefinition |