在 spring 中 beanPostProcessor 绝对是开天辟地的产物, 给了程序员很多自主权, beanPostProcessor 即常说的 bean 后置处理器.
一, 概览
先来说下 InstantiationAwareBeanPostProcessor, 这个后置处理器是 BeanPostProcessor 的子接口, 继承自 BeanPostProcessor, 先看下 BeanPostProcessor 中的方法,
再看下 InstantiationAwareBeanPostProcessor 中的方法,
可见 InstantiationAwareBeanPostProcessor 扩展了 BeanPostProcessor 接口, 并且新增了 4 个方法, 今天先看 postProcessAfterInstantiation 方法,
- default boolean postProcessAfterInstantiation(Object bean, String beanName) throws BeansException {
- return true;
- }
改方法有默认的返回值为 true.
二, 详述
InstantiationAwareBeanPostProcessor 中的 postProcessAfterInstantiation 方法的作用是什么那, 用在什么地方. 在看 spring 源码的时候看到属性注入这段代码, 其中属性注入是在 populateBean 方法中完成, 在此方法中便出现了 postProcessAfterInstatiation 方法的调用, 这里只贴出 populateBean 方法中和这块有关系的代码,
- boolean continueWithPropertyPopulation = true;
- // 调用 beanFactory 中已注册的 beanPostProcessors 即 bean 后置处理器, 判断是否为 InstantiationAwareBeanPostProcessor 的类型, 如果是执行 postProcessAfterInstantiation
- if (!mbd.isSynthetic() && hasInstantiationAwareBeanPostProcessors()) {
- for (BeanPostProcessor bp : getBeanPostProcessors()) {
- if (bp instanceof InstantiationAwareBeanPostProcessor) {
- InstantiationAwareBeanPostProcessor ibp = (InstantiationAwareBeanPostProcessor) bp;
- // 如果返回值为 false 才会进到下面的赋值操作, 从而下方的 1 处才会为 true, 则属性注入才会中断
- if (!ibp.postProcessAfterInstantiation(bw.getWrappedInstance(), beanName)) {
- continueWithPropertyPopulation = false;
- break;
- }
- }
- }
- }
- //1
- if (!continueWithPropertyPopulation) {
- return;
- }
上面这段逻辑就是来循环已经注册的 beanPostProcessor, 找到是 InstantiationAwareBeanPostProcessor 的类型, 并执行其 postProcessAfterInstantiation 方法, 通过查看已注册的 beanPostProcessor 发现其返回值均为 true, 通过上面的分析, 只有 postProcessAfterInstantiation 方法返回 false,populateBean 方法才会返回, 属性注入才会中断, 即不会注入值.
怎么才能保证 postProcessAfterInstantiation 方法返回 false 那, 这里只有自己向 spring 注册一个 InstantiationAwareBeanPostProcessor 的后置处理器, 下面是我的一个后置处理器,
- package cn.com.my.test;
- import org.springframework.beans.BeansException;
- import org.springframework.beans.factory.config.InstantiationAwareBeanPostProcessor;
- import org.springframework.stereotype.Component;
- @Component
- public class MyInstantiationAwareBeanPostProcessor implements InstantiationAwareBeanPostProcessor {
- @Override
- public boolean postProcessAfterInstantiation(Object bean, String beanName) throws BeansException {
- // TODO Auto-generated method stub
- System.out.println("beanName:"+beanName);
- if("userService".equals(beanName)) {
- return false;
- }
- return InstantiationAwareBeanPostProcessor.super.postProcessAfterInstantiation(bean, beanName);
- }
- }
自定义的 beanPostProcessor 仅实现了 postProcessAfterInstantiation 方法, 上面的代码逻辑中, 可以看到只有 beanName 为 userService 的时候, 改方法才会返回 false, 其他情况下调用的接口方法, 返回默认值 true.
下面看我的测试类,
- package cn.com.my.test;
- import org.springframework.context.annotation.AnnotationConfigApplicationContext;
- public class Test {
- public static void main(String[] args) {
- // TODO Auto-generated method stub
- AnnotationConfigApplicationContext ac=new AnnotationConfigApplicationContext(Config.class);
- UserService us=ac.getBean(UserService.class);
- System.out.println("us.roleService:"+us.getRoleService());
- }
- }
下面是我的 UserService 类,
- package cn.com.my.test;
- import org.springframework.beans.BeansException;
- import org.springframework.beans.factory.annotation.Autowired;
- import org.springframework.beans.factory.config.InstantiationAwareBeanPostProcessor;
- import org.springframework.stereotype.Component;
- @Component
- public class UserService {
- @Autowired
- private RoleService roleService;
- public RoleService getRoleService() {
- return roleService;
- }
- public void setRoleService(RoleService roleService) {
- this.roleService = roleService;
- }
- }
从 UserService 类中, 可以看出有一个加了注解的 roleService 属性, 正常情况下会自动注入改属性, 但在我自定义的 beanPostProcessor 之后, 看下面的结果
神奇的事情, 发生了 us.roleService 的属性返回的 null.
这是为什么那, 我们再看 populateBean 中的这段代码,
- boolean continueWithPropertyPopulation = true;
- // 调用 beanPostProcessors 即 bean 后置处理器,
- if (!mbd.isSynthetic() && hasInstantiationAwareBeanPostProcessors()) {
- for (BeanPostProcessor bp : getBeanPostProcessors()) {
- if (bp instanceof InstantiationAwareBeanPostProcessor) {
- InstantiationAwareBeanPostProcessor ibp = (InstantiationAwareBeanPostProcessor) bp;
- if (!ibp.postProcessAfterInstantiation(bw.getWrappedInstance(), beanName)) {
- continueWithPropertyPopulation = false;
- break;
- }
- }
- }
- }
- if (!continueWithPropertyPopulation) {
- return;
- }
由于, 我们向 beanFactory 中注册了一个 beanPostProcessor, 所以这里循环的时候肯定会执行我的 postProcessAfterInstantiation 后置处理器, 而我在后置处理器中进行了判断, 即在给 beanName 为 userService 进行属性注入的时候 postProcessAfterInstantiation 方法会返回 false, 那么上面的 continueWithPropertyPopulation 便为 false, 导致会进入到下面的 if, 方法直接返回, 属性注入便会中止, 所以 UserService 类中的 roleService 的值为 null.
三, 适用场合
什么时候需要实现 InstantiationAwareBeanPostProcessor 的 postProcessAfterInstantiation 方法那, 如果不想使用 spring 的自动注入 (前提是已经使用了 @Autowired 注解), 则对于特殊的 bean 则可以注册一个 beanPostProcessor 使其不进行注入, 使用自己的方式进行注入.
原创不易, 有不当之处, 欢迎指正, 谢谢!
来源: https://www.cnblogs.com/teach/p/12639363.html