在使用SpringBoot集成shiro时,遇到过一个问题,shiro需要注册一个LifecycleBeanPostProcessor
,用来调用内部的init()
和destroy()
方法。
一般在Configuration中注册:
在这个Configuration
中,使用@Autowired
注入会失败!
如果是在属性上使用:
使用时发现springDataSourceConfig为空;
如果用构造器注入:
会报错:
网上搜索后找到答案,原因是LifecycleBeanPostProcessor
集成了BeanPostProcessor
,而在Spring声明周期中,BeanPostProcessor
和BeanFactoryPostProcessor
的初始化是优先于bean的初始化的:
因此,如果一个@Configuration
标注的类中返回了BeanPostProcessor
或者BeanFactoryPostProcessor
,那么无法使用@Autowired
进行注入。@Bean
注解的javadoc中也有说明:
BeanFactoryPostProcessor-returning
@Bean
methods
Special consideration must be taken for@Bean
methods 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@PostConstruct
within@Configuration
classes. To avoid these lifecycle issues, mark BFPP-returning@Bean
methods 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
@Configuration
class, thus avoiding the above-mentioned lifecycle conflicts. Note however that static@Bean
methods 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@Bean
methods. As a reminder, a WARN-level log message will be issued for any non-static@Bean
methods having a return type assignable to BeanFactoryPostProcessor.
解决的方案javadoc中也说了,就是给返回BeanPostProcessor
或者BeanFactoryPostProcessor
的方法使用static修饰。
这样,调用该方法时,不需要实例化外层的容器。
|
|
参考:
Spring Java based configuration with static method
Spring Bean的生命周期