全部学科
NodeJS全栈
nodejs
Python全栈
python
小程序首页
📅 2026-05-18 10 分钟 ✍️ juanwangdev

Spring Boot BeanPostProcessor扩展

BeanPostProcessor 是 Spring 容器扩展的核心接口。

接口定义

Java
public interface BeanPostProcessor {

    // Bean初始化前调用
    @Nullable
    default Object postProcessBeforeInitialization(
            Object bean, String beanName) throws BeansException {
        return bean;
    }

    // Bean初始化后调用
    @Nullable
    default Object postProcessAfterInitialization(
            Object bean, String beanName) throws BeansException {
        return bean;
    }
}

执行时机

Java
实例化Bean → 属性注入 → postProcessBeforeInitialization
         → @PostConstruct → InitializingBean.afterPropertiesSet
         → postProcessAfterInitialization → Bean就绪

基础示例

Java
@Component
@Slf4j
public class LoggingBeanPostProcessor implements BeanPostProcessor {

    @Override
    public Object postProcessBeforeInitialization(
            Object bean, String beanName) throws BeansException {

        if (bean.getClass().isAnnotationPresent(Loggable.class)) {
            log.info("初始化Bean: {}", beanName);
        }
        return bean;
    }

    @Override
    public Object postProcessAfterInitialization(
            Object bean, String beanName) throws BeansException {

        if (bean.getClass().isAnnotationPresent(Loggable.class)) {
            log.info("Bean就绪: {}", beanName);
        }
        return bean;
    }
}

实现动态代理

Java
@Component
public class TimingBeanPostProcessor implements BeanPostProcessor {

    @Override
    public Object postProcessAfterInitialization(
            Object bean, String beanName) throws BeansException {

        // 只处理带@Timed注解的Bean
        if (!hasTimedMethods(bean.getClass())) {
            return bean;
        }

        return Proxy.newProxyInstance(
            bean.getClass().getClassLoader(),
            bean.getClass().getInterfaces(),
            (proxy, method, args) -> {
                if (method.isAnnotationPresent(Timed.class)) {
                    long start = System.currentTimeMillis();
                    Object result = method.invoke(bean, args);
                    long duration = System.currentTimeMillis() - start;
                    log.info("{}.{} 执行耗时: {}ms",
                        bean.getClass().getSimpleName(),
                        method.getName(), duration);
                    return result;
                }
                return method.invoke(bean, args);
            });
    }

    private boolean hasTimedMethods(Class<?> clazz) {
        for (Method method : clazz.getMethods()) {
            if (method.isAnnotationPresent(Timed.class)) {
                return true;
            }
        }
        return false;
    }
}

属性解密处理器

Java
@Component
public class DecryptBeanPostProcessor implements BeanPostProcessor {

    @Override
    public Object postProcessBeforeInitialization(
            Object bean, String beanName) throws BeansException {

        for (Field field : bean.getClass().getDeclaredFields()) {
            if (field.isAnnotationPresent(Encrypted.class)) {
                field.setAccessible(true);
                try {
                    String value = (String) field.get(bean);
                    field.set(bean, decrypt(value));
                } catch (IllegalAccessException e) {
                    throw new RuntimeException(e);
                }
            }
        }
        return bean;
    }

    private String decrypt(String encrypted) {
        // 解密逻辑
        return AESUtil.decrypt(encrypted);
    }
}

Bean验证处理器

Java
@Component
public class ValidationBeanPostProcessor implements BeanPostProcessor {

    @Override
    public Object postProcessAfterInitialization(
            Object bean, String beanName) throws BeansException {

        if (bean instanceof Validatable) {
            ((Validatable) bean).validate();
        }

        return bean;
    }
}

public interface Validatable {
    void validate();
}

@Service
public class ConfigService implements Validatable {

    @Value("${app.timeout}")
    private int timeout;

    @Override
    public void validate() {
        if (timeout <= 0) {
            throw new IllegalStateException("timeout必须大于0");
        }
    }
}

Spring内置处理器

处理器功能
AutowiredAnnotationBeanPostProcessor处理@Autowired
CommonAnnotationBeanPostProcessor处理@Resource、@PostConstruct
AnnotationAwareAspectJAutoProxyCreatorAOP代理创建
ApplicationContextAwareProcessor注入ApplicationContext

注意事项

text
@Component
public class MyBeanPostProcessor implements BeanPostProcessor {

    // ❌ 错误:不要在BeanPostProcessor中使用@Autowired
    // @Autowired
    // private OtherService otherService;

    // ✅ 正确:通过构造函数注入
    public MyBeanPostProcessor(OtherService otherService) {
        this.otherService = otherService;
    }

    // ❌ 错误:不要过早引用其他Bean
    // 可能导致循环依赖或Bean未初始化

    // ✅ 正确:返回null或原Bean
    @Override
    public Object postProcessBeforeInitialization(
            Object bean, String beanName) {
        return bean;  // 不修改则返回原Bean
    }
}

BeanPostProcessor执行时机早于普通Bean,注意避免循环依赖。

要点总结

  • Before在初始化前,After在初始化后
  • 可返回代理对象实现AOP功能
  • 不应注入其他Bean避免循环依赖
  • Spring内置多个关键处理器

📝 发现内容有误?点击此处直接编辑

← 上一篇 Spring Boot Actuator端点扩展
下一篇 → Spring Boot EnvironmentPostProcessor扩展
想查看更多题目和详细解析?
小程序提供完整的题库、模拟考试和详细解析
马上就来

长按或扫描二维码,立即体验

扫码体验小程序
马上就来
使用微信扫描二维码
立即体验完整题库