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 |
| AnnotationAwareAspectJAutoProxyCreator | AOP代理创建 |
| 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内置多个关键处理器
📝 发现内容有误?点击此处直接编辑