文
章
目
录
章
目
录
最近潘老师在搭建SpringBoot项目整合Shiro框架时,在@Configuration
注解的类中使用@Autowired
或@Resource
等注解自动注入service
对象时,在启动后无法获取注入的对象值,始终为null
,经过一番查找终于找到了解决方案。
一、先看问题代码
1)service
层代码
@Service public class ShiroServiceImpl implements ShiroService { @Override public Map<String, String> loadFilterChainDefinitions() { // 省略.... } }
2)@Configuration
类部分代码
@Configuration public class ShiroConfig { @Autowired private ShiroService shiroService; @Bean("shiroFilter") public ShiroFilterFactoryBean shiroFilter(SecurityManager securityManager) { ShiroFilterFactoryBean shiroFilter = new ShiroFilterFactoryBean(); // 省略部分代码.... // shiroService调用会报空指针异常 Map<String, String> filterChainDefinitionMap = shiroService.loadFilterChainDefinitions(); shiroFilter.setFilterChainDefinitionMap(filterChainDefinitionMap); return shiroFilter; } }
潘老师测试发现@Autowired
进来的shiroService
始终为null,导致调用方法报空指针异常,说明@Autowired
注入失败了。
二、注入失败的原因
首先我们分析下注入失败的原因,在经过测试,潘老师发现,主要原因就在于@Configuration
注解的类会优先于其他@Component
或@Service
注解的类创建,也就是说,当@Configuration
类创建时需要自动注入shiroService
时,其实此时被@Service
修饰的ShiroService
还没有被创建呢,所以自动注入的就是null,导致注入失败。
三、解决办法
解决方法很简单,就是不要使用自动注入,直接将你需要的依赖的对象以参数的方式放在@Bean
修饰的方法中即可,因此@Configuration
类部分代码修改如下:
@Configuration public class ShiroConfig { @Bean("shiroFilter") public ShiroFilterFactoryBean shiroFilter(SecurityManager securityManager, ShiroService shiroService) { ShiroFilterFactoryBean shiroFilter = new ShiroFilterFactoryBean(); // 省略部分代码.... // debug调试发现shiroService正常调用 Map<String, String> filterChainDefinitionMap = shiroService.loadFilterChainDefinitions(); shiroFilter.setFilterChainDefinitionMap(filterChainDefinitionMap); return shiroFilter; } }
以上是潘老师亲自测试的结果,此种方法确实能解决该问题,之前潘老师也试图使用@Order
来降低@Configuration
类创建的优先级提高shiroService
的创建优先级,但是并没有效果,配置类始终优先于其他类,因此如果你也还有什么问题可以联系潘老师,若有更好的解决方案,也希望能留言评论,大家一起交流学习!