为何在BeanPostProcessor中使用@Value可正常运行?与Spring文档不符
Spring官方文档提到:@Autowired、@Inject、@Value和@Resource注解由Spring的BeanPostProcessor实现类处理,因此不能在自定义的BeanPostProcessor或BeanFactoryPostProcessor类型中使用这些注解,此类组件必须通过XML或Spring @Bean方法显式装配。
但实际测试时,如下代码却能正常运行:
测试代码
application.properties
application.name=demo
自定义BeanPostProcessor实现
@Component public class DemoPostProcessor implements BeanPostProcessor { @Value("${application.name}") String applicationName; @PostConstruct void postConstruct() { System.out.println("===>" + applicationName); // 正确输出 `===>demo` } }
背后的原因
这并不是文档描述有误,而是你忽略了Spring对BeanPostProcessor的特殊处理逻辑:
Spring对BeanPostProcessor的提前初始化与依赖注入
Spring启动时会优先识别并初始化所有BeanPostProcessor类型的Bean。为了避免依赖处理的死循环,Spring会绕过常规的BeanPostProcessor链,专门为这些BeanPostProcessor自身执行依赖注入逻辑——包括@Autowired、@Value的解析,确保它们能正常工作。文档描述的是严谨的"原理场景"
文档的说法是从依赖顺序的本质出发:普通Bean的@Autowired依赖是由AutowiredAnnotationBeanPostProcessor这类后置处理器完成的,但BeanPostProcessor的初始化早于这些后置处理器的完全生效。原本按照设计逻辑,这类注解确实不应该在BeanPostProcessor中生效,但Spring为了提升开发便利性,额外添加了特殊处理逻辑。存在潜在风险的场景
这种用法并非绝对安全:如果你的BeanPostProcessor依赖的是一个需要被其他BeanPostProcessor处理的Bean,或者依赖的Bean还未完成初始化,就可能出现注入未完全实例化对象的问题。另外在Spring 3.x及更早的版本中,并没有这种特殊处理,此时就会出现文档中描述的注解失效问题。
内容的提问来源于stack exchange,提问作者asgarov1

