【附录】BeanPostProcessor的作用时机与核心实现?

158 阅读6分钟

【附录】BeanPostProcessor的作用时机与核心实现?

此文是【Spring 容器详解】的支节点。

什么是BeanPostProcessor

BeanPostProcessor是Spring提供的一个扩展点,它允许在Bean实例化过程中对Bean进行增强或修改。BeanPostProcessor是一个接口,Spring容器会调用它的两个方法:

public interface BeanPostProcessor {
    // Bean初始化前的处理
    Object postProcessBeforeInitialization(Object bean, String beanName);
    
    // Bean初始化后的处理
    Object postProcessAfterInitialization(Object bean, String beanName);
}

作用时机

BeanPostProcessor在Bean的生命周期中的执行时机:

1. 实例化Bean (new)
2. 设置属性值 (setter注入)
3. 调用BeanPostProcessor.postProcessBeforeInitialization()
4. 调用@PostConstruct方法
5. 调用InitializingBean.afterPropertiesSet()
6. 调用自定义init方法
7. 调用BeanPostProcessor.postProcessAfterInitialization()
8. Bean可以使用了

BeanPostProcessor的核心实现

1. InstantiationAwareBeanPostProcessor

这个接口在Bean实例化之前和之后进行干预:

public interface InstantiationAwareBeanPostProcessor extends BeanPostProcessor {
    
    // 在Bean实例化之前调用,可以返回一个代理对象来替代目标Bean
    Object postProcessBeforeInstantiation(Class<?> beanClass, String beanName);
    
    // 在Bean实例化之后,属性设置之前调用
    boolean postProcessAfterInstantiation(Object bean, String beanName);
    
    // 在属性设置之前调用,可以修改属性值
    PropertyValues postProcessProperties(PropertyValues pvs, Object bean, String beanName);
}

使用示例:

@Component
public class CustomInstantiationAwareBeanPostProcessor implements InstantiationAwareBeanPostProcessor {
    
    @Override
    public Object postProcessBeforeInstantiation(Class<?> beanClass, String beanName) {
        // 在Bean实例化之前,可以返回一个代理对象
        if (beanClass == UserService.class) {
            System.out.println("在UserService实例化之前进行干预");
            // 可以返回一个代理对象来替代原始Bean
            return Proxy.newProxyInstance(
                beanClass.getClassLoader(),
                beanClass.getInterfaces(),
                (proxy, method, args) -> {
                    System.out.println("代理方法执行: " + method.getName());
                    return method.invoke(new UserService(), args);
                }
            );
        }
        return null; // 返回null表示不干预,使用默认实例化
    }
    
    @Override
    public boolean postProcessAfterInstantiation(Object bean, String beanName) {
        // 在Bean实例化之后,属性设置之前调用
        if (bean instanceof UserService) {
            System.out.println("UserService实例化完成,即将设置属性");
        }
        return true; // 返回true表示继续属性设置
    }
    
    @Override
    public PropertyValues postProcessProperties(PropertyValues pvs, Object bean, String beanName) {
        // 在属性设置之前调用,可以修改属性值
        if (bean instanceof UserService) {
            MutablePropertyValues mutablePvs = new MutablePropertyValues(pvs);
            // 修改某个属性值
            mutablePvs.add("userDao", new RuntimeBeanReference("customUserDao"));
            return mutablePvs;
        }
        return pvs;
    }
}

2. SmartInstantiationAwareBeanPostProcessor

这个接口提供了更智能的实例化处理:

public interface SmartInstantiationAwareBeanPostProcessor extends InstantiationAwareBeanPostProcessor {
    
    // 预测Bean的类型
    Class<?> predictBeanType(Class<?> beanClass, String beanName);
    
    // 确定构造器
    Constructor<?>[] determineCandidateConstructors(Class<?> beanClass, String beanName);
    
    // 获取早期引用(用于解决循环依赖)
    Object getEarlyBeanReference(Object bean, String beanName);
}

使用示例:

@Component
public class CustomSmartInstantiationAwareBeanPostProcessor implements SmartInstantiationAwareBeanPostProcessor {
    
    @Override
    public Class<?> predictBeanType(Class<?> beanClass, String beanName) {
        // 预测Bean的实际类型
        if (beanClass == UserService.class) {
            return UserServiceImpl.class; // 返回实际的实现类
        }
        return beanClass;
    }
    
    @Override
    public Constructor<?>[] determineCandidateConstructors(Class<?> beanClass, String beanName) {
        // 确定使用哪个构造器
        if (beanClass == UserService.class) {
            try {
                // 返回特定的构造器
                return new Constructor<?>[]{
                    beanClass.getConstructor(UserDao.class, EmailService.class)
                };
            } catch (NoSuchMethodException e) {
                return null;
            }
        }
        return null; // 返回null表示使用默认构造器
    }
    
    @Override
    public Object getEarlyBeanReference(Object bean, String beanName) {
        // 获取早期引用,用于解决循环依赖
        if (bean instanceof UserService) {
            // 可以在这里创建代理对象
            return Proxy.newProxyInstance(
                bean.getClass().getClassLoader(),
                bean.getClass().getInterfaces(),
                new EarlyBeanReferenceInvocationHandler(bean)
            );
        }
        return bean;
    }
}

3. MergedBeanDefinitionPostProcessor

这个接口在BeanDefinition合并后进行干预:

public interface MergedBeanDefinitionPostProcessor extends BeanPostProcessor {
    
    // 在BeanDefinition合并后调用
    void postProcessMergedBeanDefinition(RootBeanDefinition beanDefinition, Class<?> beanType, String beanName);
}

使用示例:

@Component
public class CustomMergedBeanDefinitionPostProcessor implements MergedBeanDefinitionPostProcessor {
    
    @Override
    public void postProcessMergedBeanDefinition(RootBeanDefinition beanDefinition, Class<?> beanType, String beanName) {
        // 在BeanDefinition合并后,可以修改BeanDefinition
        if (beanType == UserService.class) {
            // 添加自定义的初始化方法
            beanDefinition.setInitMethodName("customInit");
            
            // 设置作用域
            beanDefinition.setScope("prototype");
            
            // 添加依赖
            beanDefinition.setDependsOn("userDao", "emailService");
        }
    }
}

Spring内置的BeanPostProcessor

1. AutowiredAnnotationBeanPostProcessor

处理@Autowired注解的依赖注入:

@Component
public class AutowiredAnnotationBeanPostProcessor implements SmartInstantiationAwareBeanPostProcessor {
    
    @Override
    public PropertyValues postProcessProperties(PropertyValues pvs, Object bean, String beanName) {
        // 处理@Autowired注解
        ReflectionUtils.doWithFields(bean.getClass(), field -> {
            Autowired autowired = field.getAnnotation(Autowired.class);
            if (autowired != null) {
                // 获取依赖的Bean
                Object dependency = getBean(field.getType());
                // 设置字段值
                field.setAccessible(true);
                field.set(bean, dependency);
            }
        });
        return pvs;
    }
}

2. CommonAnnotationBeanPostProcessor

处理@Resource、@PostConstruct、@PreDestroy等注解:

@Component
public class CommonAnnotationBeanPostProcessor implements InstantiationAwareBeanPostProcessor {
    
    @Override
    public Object postProcessBeforeInitialization(Object bean, String beanName) {
        // 处理@PostConstruct注解
        ReflectionUtils.doWithMethods(bean.getClass(), method -> {
            PostConstruct postConstruct = method.getAnnotation(PostConstruct.class);
            if (postConstruct != null) {
                method.setAccessible(true);
                method.invoke(bean);
            }
        });
        return bean;
    }
    
    @Override
    public Object postProcessAfterInitialization(Object bean, String beanName) {
        // 注册@PreDestroy方法
        ReflectionUtils.doWithMethods(bean.getClass(), method -> {
            PreDestroy preDestroy = method.getAnnotation(PreDestroy.class);
            if (preDestroy != null) {
                // 注册销毁方法
                registerDisposableBean(bean, method);
            }
        });
        return bean;
    }
}

3. AnnotationAwareAspectJAutoProxyCreator

处理AOP代理的创建:

@Component
public class AnnotationAwareAspectJAutoProxyCreator extends AbstractAutoProxyCreator {
    
    @Override
    public Object postProcessAfterInitialization(Object bean, String beanName) {
        // 检查是否需要创建AOP代理
        if (shouldCreateProxy(bean, beanName)) {
            // 创建AOP代理
            return createProxy(bean, beanName);
        }
        return bean;
    }
    
    private boolean shouldCreateProxy(Object bean, String beanName) {
        // 检查是否有@Aspect注解的类
        // 检查是否有匹配的切点
        return hasMatchingAspects(bean, beanName);
    }
    
    private Object createProxy(Object bean, String beanName) {
        // 创建JDK动态代理或CGLIB代理
        return ProxyFactory.getProxy(bean);
    }
}

4. ApplicationListenerDetector

检测ApplicationListener接口的实现:

@Component
public class ApplicationListenerDetector implements MergedBeanDefinitionPostProcessor {
    
    @Override
    public void postProcessMergedBeanDefinition(RootBeanDefinition beanDefinition, Class<?> beanType, String beanName) {
        // 检查是否是ApplicationListener的实现
        if (ApplicationListener.class.isAssignableFrom(beanType)) {
            // 标记为ApplicationListener
            beanDefinition.setApplicationListener(true);
        }
    }
    
    @Override
    public Object postProcessAfterInitialization(Object bean, String beanName) {
        // 如果是ApplicationListener,注册到事件多播器
        if (bean instanceof ApplicationListener) {
            applicationEventMulticaster.addApplicationListener((ApplicationListener<?>) bean);
        }
        return bean;
    }
}

自定义BeanPostProcessor示例

1. 性能监控BeanPostProcessor

@Component
public class PerformanceMonitorBeanPostProcessor implements BeanPostProcessor {
    
    private final Map<String, Long> startTimes = new ConcurrentHashMap<>();
    
    @Override
    public Object postProcessBeforeInitialization(Object bean, String beanName) {
        // 记录初始化开始时间
        startTimes.put(beanName, System.currentTimeMillis());
        System.out.println("开始初始化Bean: " + beanName);
        return bean;
    }
    
    @Override
    public Object postProcessAfterInitialization(Object bean, String beanName) {
        // 计算初始化耗时
        Long startTime = startTimes.remove(beanName);
        if (startTime != null) {
            long duration = System.currentTimeMillis() - startTime;
            System.out.println("Bean初始化完成: " + beanName + ", 耗时: " + duration + "ms");
        }
        return bean;
    }
}

2. 属性加密BeanPostProcessor

@Component
public class PropertyEncryptionBeanPostProcessor implements BeanPostProcessor {
    
    @Override
    public Object postProcessBeforeInitialization(Object bean, String beanName) {
        // 解密敏感属性
        if (bean instanceof DatabaseConfig) {
            DatabaseConfig config = (DatabaseConfig) bean;
            config.setPassword(decrypt(config.getPassword()));
        }
        return bean;
    }
    
    private String decrypt(String encryptedValue) {
        // 解密逻辑
        return "decrypted_" + encryptedValue;
    }
}

3. Bean验证BeanPostProcessor

@Component
public class BeanValidationBeanPostProcessor implements BeanPostProcessor {
    
    @Override
    public Object postProcessAfterInitialization(Object bean, String beanName) {
        // 验证Bean的完整性
        if (bean instanceof UserService) {
            UserService userService = (UserService) bean;
            if (userService.getUserDao() == null) {
                throw new IllegalStateException("UserService缺少UserDao依赖");
            }
        }
        return bean;
    }
}

4. Bean统计BeanPostProcessor

@Component
public class BeanStatisticsBeanPostProcessor implements BeanPostProcessor {
    
    private final AtomicInteger beanCount = new AtomicInteger(0);
    private final Set<String> beanTypes = new ConcurrentHashSet<>();
    
    @Override
    public Object postProcessAfterInitialization(Object bean, String beanName) {
        // 统计Bean信息
        beanCount.incrementAndGet();
        beanTypes.add(bean.getClass().getSimpleName());
        
        System.out.println("当前Bean总数: " + beanCount.get());
        System.out.println("Bean类型: " + beanTypes);
        
        return bean;
    }
}

BeanPostProcessor的执行顺序

1. 优先级控制

@Component
@Order(1) // 使用@Order注解控制执行顺序
public class HighPriorityBeanPostProcessor implements BeanPostProcessor {
    
    @Override
    public Object postProcessBeforeInitialization(Object bean, String beanName) {
        System.out.println("高优先级处理器执行");
        return bean;
    }
    
    @Override
    public Object postProcessAfterInitialization(Object bean, String beanName) {
        return bean;
    }
}

@Component
@Order(2)
public class LowPriorityBeanPostProcessor implements BeanPostProcessor {
    
    @Override
    public Object postProcessBeforeInitialization(Object bean, String beanName) {
        System.out.println("低优先级处理器执行");
        return bean;
    }
    
    @Override
    public Object postProcessAfterInitialization(Object bean, String beanName) {
        return bean;
    }
}

2. 实现PriorityOrdered接口

@Component
public class CustomPriorityBeanPostProcessor implements BeanPostProcessor, PriorityOrdered {
    
    @Override
    public int getOrder() {
        return Ordered.HIGHEST_PRECEDENCE; // 最高优先级
    }
    
    @Override
    public Object postProcessBeforeInitialization(Object bean, String beanName) {
        return bean;
    }
    
    @Override
    public Object postProcessAfterInitialization(Object bean, String beanName) {
        return bean;
    }
}

总结

BeanPostProcessor的核心特点:

  1. 扩展性强 - 允许在Bean生命周期中插入自定义逻辑
  2. 时机灵活 - 可以在Bean实例化、初始化前后进行干预
  3. 功能丰富 - 支持属性修改、代理创建、验证等多种功能
  4. 顺序可控 - 通过@Order注解或PriorityOrdered接口控制执行顺序

不同实现的功能差异:

  1. InstantiationAwareBeanPostProcessor - 在实例化前后干预
  2. SmartInstantiationAwareBeanPostProcessor - 提供更智能的实例化处理
  3. MergedBeanDefinitionPostProcessor - 在BeanDefinition合并后干预
  4. 内置处理器 - 处理注解、AOP、事件等特定功能

使用场景:

  1. 性能监控 - 监控Bean的创建和初始化时间
  2. 属性处理 - 加密解密、格式转换等
  3. 验证检查 - 验证Bean的完整性和正确性
  4. 代理创建 - 创建AOP代理或其他代理对象
  5. 统计信息 - 收集Bean的统计信息

BeanPostProcessor是Spring框架中非常重要的扩展点,它提供了强大的Bean生命周期干预能力,是理解Spring内部机制的关键。