Spring boot 整合shiro 使用yml配置文件
最近自己玩一下springBoot配置 然后整合一下常用的框架,遇到一个问题。配置LifecycleBeanPostProcessorBean 的时候总是先于spring 读取yml文件。导致配置失败
@Bean(name = "shiroEhcacheManager")
public EhCacheManager getEhCacheManager() {
EhCacheManager em = new EhCacheManager();
em.setCacheManagerConfigFile(cacheManagerConfigFilePath);
return em;
}
Error initializing bean [shiroEhcacheManager]; nested exception is org.apache.shiro.cache.CacheException:
java.lang.NullPointerException
很显然报出了一个空指针的错误,也就是 cacheManagerConfigFilePath 的值没有初始化成功,我原先以为我的yml文件配置错误,
回去检查了没问题,
于是我开始一个一个Bean 进行初始化,下面是我整个config的配置
- @Configuration
- @ConfigurationProperties(prefix = "shiro")
- public class ShiroConfiguration {
-
- private String cacheManagerConfigFilePath;
- private String loginUrl;
- private String successUrl;
-
- private Map filterChainDefinitionMap = new LinkedHashMap();
-
- @Bean(name = "shiroRealm")
- public ShiroRealm getShiroRealm() {
- return new ShiroRealm();
- }
-
- @Bean(name = "shiroEhcacheManager")
- public EhCacheManager getEhCacheManager() {
- EhCacheManager em = new EhCacheManager();
- em.setCacheManagerConfigFile(cacheManagerConfigFilePath);
- return em;
- }
-
- @Bean(name = "lifecycleBeanPostProcessor")
- public static LifecycleBeanPostProcessor getLifecycleBeanPostProcessor() {
- return new LifecycleBeanPostProcessor();
- }
-
- @Bean
- public DefaultAdvisorAutoProxyCreator getDefaultAdvisorAutoProxyCreator() {
- DefaultAdvisorAutoProxyCreator daap = new DefaultAdvisorAutoProxyCreator();
- daap.setProxyTargetClass(true);
- return daap;
- }
-
- @Bean(name = "securityManager")
- public DefaultWebSecurityManager getDefaultWebSecurityManager(AuthorizingRealm shiroRealm,EhCacheManager ehCacheManager) {
- DefaultWebSecurityManager dwsm = new DefaultWebSecurityManager();
- dwsm.setRealm(shiroRealm);
- dwsm.setCacheManager(ehCacheManager);
- return dwsm;
- }
-
- @Bean
- public AuthorizationAttributeSourceAdvisor getAuthorizationAttributeSourceAdvisor(SecurityManager securityManager) {
- AuthorizationAttributeSourceAdvisor aasa = new AuthorizationAttributeSourceAdvisor();
- aasa.setSecurityManager(securityManager);
- return new AuthorizationAttributeSourceAdvisor();
- }
-
- @Bean(name = "shiroFilter")
- public ShiroFilterFactoryBean getShiroFilterFactoryBean(SecurityManager securityManager) {
- ShiroFilterFactoryBean shiroFilterFactoryBean = new ShiroFilterFactoryBean();
- shiroFilterFactoryBean
- .setSecurityManager(securityManager);
- shiroFilterFactoryBean.setLoginUrl(loginUrl);
- shiroFilterFactoryBean.setSuccessUrl(successUrl);
-
-
- System.out.println(filterChainDefinitionMap);
- shiroFilterFactoryBean
- .setFilterChainDefinitionMap(filterChainDefinitionMap);
- return shiroFilterFactoryBean;
- }
-
- public String getCacheManagerConfigFilePath() {
- return cacheManagerConfigFilePath;
- }
-
- public void setCacheManagerConfigFilePath(String cacheManagerConfigFilePath) {
- this.cacheManagerConfigFilePath = cacheManagerConfigFilePath;
- }
-
- public String getLoginUrl() {
- return loginUrl;
- }
-
- public void setLoginUrl(String loginUrl) {
- this.loginUrl = loginUrl;
- }
-
- public String getSuccessUrl() {
- return successUrl;
- }
-
- public void setSuccessUrl(String successUrl) {
- this.successUrl = successUrl;
- }
-
- public Map getFilterChainDefinitionMap() {
- return filterChainDefinitionMap;
- }
-
- public void setFilterChainDefinitionMap(Map filterChainDefinitionMap) {
- this.filterChainDefinitionMap = filterChainDefinitionMap;
- }
- }
如果我注释掉shiroEhcacheManager 以下所有bean的创建,项目能启动,当我@Bean(name = "lifecycleBeanPostProcessor")
创建这个bean的时候就抛出了上面的异常。这么分析过来问题应该出在这个bean上。
百度了一下,
LifecycleBeanPostProcessor用于在实现了Initializable接口的Shiro bean初始化时调用Initializable接口回调,在实现了Destroyable接口的
Shiro bean销毁时调用 Destroyable接口回调。
而我在创建的EhCacheManager 正是实现了Initializable接口,下面我截图了一张官方的在配置上面的说明
BeanFactoryPostProcessor的时候(LifecycleBeanPostProcessor正是BeanPostProcessor 的子类)。应该讲这些创建Bean的方法前面加上static。让使用configuration的类在没有实例化的时候不会去过早的要求@Autowired和@Value
进行注入。
最后解决问题很简单,只要在创建LifecycleBeanPostProcessor的方法变为静态static方法。
其实我也没有彻底弄清楚出现这个问题的根本原因,如果有其他人知道的话,请指出来共同学习。