在使用SpringBoot集成shiro时,遇到过一个问题,shiro需要注册一个LifecycleBeanPostProcessor,用来调用内部的init()和destroy()方法。
一般在Configuration中注册:
在这个Configuration中,使用@Autowired注入会失败!
如果是在属性上使用:
使用时发现springDataSourceConfig为空;
如果用构造器注入:
会报错:
网上搜索后找到答案,原因是LifecycleBeanPostProcessor集成了BeanPostProcessor,而在Spring声明周期中,BeanPostProcessor和BeanFactoryPostProcessor的初始化是优先于bean的初始化的:


因此,如果一个@Configuration标注的类中返回了BeanPostProcessor或者BeanFactoryPostProcessor,那么无法使用@Autowired进行注入。@Bean注解的javadoc中也有说明:
BeanFactoryPostProcessor-returning
@Beanmethods
Special consideration must be taken for@Beanmethods that return Spring BeanFactoryPostProcessor (BFPP) types. Because BFPP objects must be instantiated very early in the container lifecycle, they can interfere(干涉) with processing of annotations such as@Autowired,@Value, and@PostConstructwithin@Configurationclasses. To avoid these lifecycle issues, mark BFPP-returning@Beanmethods as static. For example:
1234 public static PropertyPlaceholderConfigurer ppc() {// instantiate, configure and return ppc ...}By marking this method as static, it can be invoked without causing instantiation of its declaring
@Configurationclass, thus avoiding the above-mentioned lifecycle conflicts. Note however that static@Beanmethods will not be enhanced for scoping and AOP semantics as mentioned above. This works out in BFPP cases, as they are not typically referenced by other@Beanmethods. As a reminder, a WARN-level log message will be issued for any non-static@Beanmethods having a return type assignable to BeanFactoryPostProcessor.
解决的方案javadoc中也说了,就是给返回BeanPostProcessor或者BeanFactoryPostProcessor的方法使用static修饰。
这样,调用该方法时,不需要实例化外层的容器。
|
|
参考:
Spring Java based configuration with static method
Spring Bean的生命周期