简介
说明
本文介绍使用SpringBoot整合Shiro时打印”is not eligible for getting processed by all BeanPostProcessors”的原因以及解决方案。
问题描述
使用SpringBoot整合Shiro时发现有如下输出:
2021-08-14 17:53:25.145 INFO 80884 --- [ main] trationDelegate$BeanPostProcessorChecker : Bean 'sqlSessionFactory' of type [org.apache.ibatis.session.defaults.DefaultSqlSessionFactory] is not eligible for getting processed by all BeanPostProcessors (for example: not eligible for auto-proxying) 2021-08-14 17:53:25.152 INFO 80884 --- [ main] trationDelegate$BeanPostProcessorChecker : Bean 'sqlSessionTemplate' of type [org.mybatis.spring.SqlSessionTemplate] is not eligible for getting processed by all BeanPostProcessors (for example: not eligible for auto-proxying) 2021-08-14 17:53:25.367 INFO 80884 --- [ main] trationDelegate$BeanPostProcessorChecker : Bean 'userMapper' of type [org.mybatis.spring.mapper.MapperFactoryBean] is not eligible for getting processed by all BeanPostProcessors (for example: not eligible for auto-proxying) 2021-08-14 17:53:25.369 INFO 80884 --- [ main] trationDelegate$BeanPostProcessorChecker : Bean 'userMapper' of type [com.sun.proxy.$Proxy63] is not eligible for getting processed by all BeanPostProcessors (for example: not eligible for auto-proxying) 2021-08-14 17:53:25.378 INFO 80884 --- [ main] trationDelegate$BeanPostProcessorChecker : Bean 'userServiceImpl' of type [com.example.demo.business.rbac.user.service.impl.UserServiceImpl] is not eligible for getting processed by all BeanPostProcessors (for example: not eligible for auto-proxying) 2021-08-14 17:53:25.444 INFO 80884 --- [ main] trationDelegate$BeanPostProcessorChecker : Bean 'roleMapper' of type [org.mybatis.spring.mapper.MapperFactoryBean] is not eligible for getting processed by all BeanPostProcessors (for example: not eligible for auto-proxying) 2021-08-14 17:53:25.445 INFO 80884 --- [ main] trationDelegate$BeanPostProcessorChecker : Bean 'roleMapper' of type [com.sun.proxy.$Proxy67] is not eligible for getting processed by all BeanPostProcessors (for example: not eligible for auto-proxying) 2021-08-14 17:53:25.448 INFO 80884 --- [ main] trationDelegate$BeanPostProcessorChecker : Bean 'roleServiceImpl' of type [com.example.demo.business.rbac.role.service.impl.RoleServiceImpl] is not eligible for getting processed by all BeanPostProcessors (for example: not eligible for auto-proxying) 2021-08-14 17:53:25.482 INFO 80884 --- [ main] trationDelegate$BeanPostProcessorChecker : Bean 'permissionMapper' of type [org.mybatis.spring.mapper.MapperFactoryBean] is not eligible for getting processed by all BeanPostProcessors (for example: not eligible for auto-proxying) 2021-08-14 17:53:25.483 INFO 80884 --- [ main] trationDelegate$BeanPostProcessorChecker : Bean 'permissionMapper' of type [com.sun.proxy.$Proxy69] is not eligible for getting processed by all BeanPostProcessors (for example: not eligible for auto-proxying) 2021-08-14 17:53:25.485 INFO 80884 --- [ main] trationDelegate$BeanPostProcessorChecker : Bean 'permissionServiceImpl' of type [com.example.demo.business.rbac.permission.service.impl.PermissionServiceImpl] is not eligible for getting processed by all BeanPostProcessors (for example: not eligible for auto-proxying) 2021-08-14 17:53:25.486 INFO 80884 --- [ main] trationDelegate$BeanPostProcessorChecker : Bean 'getDatabaseRealm' of type [com.example.demo.config.shiro.realm.DatabaseRealm] is not eligible for getting processed by all BeanPostProcessors (for example: not eligible for auto-proxying) 2021-08-14 17:53:25.491 INFO 80884 --- [ main] trationDelegate$BeanPostProcessorChecker : Bean 'sessionManager' of type [org.apache.shiro.web.session.mgt.DefaultWebSessionManager] is not eligible for getting processed by all BeanPostProcessors (for example: not eligible for auto-proxying) 2021-08-14 17:53:25.493 INFO 80884 --- [ main] trationDelegate$BeanPostProcessorChecker : Bean 'securityManager' of type [org.apache.shiro.web.mgt.DefaultWebSecurityManager] is not eligible for getting processed by all BeanPostProcessors (for example: not eligible for auto-proxying) 2021-08-14 17:53:25.504 INFO 80884 --- [ main] trationDelegate$BeanPostProcessorChecker : Bean 'authorizationAttributeSourceAdvisor' of type [org.apache.shiro.spring.security.interceptor.AuthorizationAttributeSourceAdvisor] is not eligible for getting processed by all BeanPostProcessors (for example: not eligible for auto-proxying) 2021-08-14 17:53:25.530 INFO 80884 --- [ main] trationDelegate$BeanPostProcessorChecker : Bean 'eventBus' of type [org.apache.shiro.event.support.DefaultEventBus] is not eligible for getting processed by all BeanPostProcessors (for example: not eligible for auto-proxying) 2021-08-14 17:53:25.539 INFO 80884 --- [ main] trationDelegate$BeanPostProcessorChecker : Bean 'shiroFilterChainDefinition' of type [org.apache.shiro.spring.web.config.DefaultShiroFilterChainDefinition] is not eligible for getting processed by all BeanPostProcessors (for example: not eligible for auto-proxying) 2021-08-14 17:53:25.543 INFO 80884 --- [ main] trationDelegate$BeanPostProcessorChecker : Bean 'requestContextFilter' of type [org.springframework.boot.web.servlet.filter.OrderedRequestContextFilter] is not eligible for getting processed by all BeanPostProcessors (for example: not eligible for auto-proxying) 2021-08-14 17:53:25.551 INFO 80884 --- [ main] trationDelegate$BeanPostProcessorChecker : Bean 'org.springframework.boot.autoconfigure.web.servlet.WebMvcAutoConfiguration' of type [org.springframework.boot.autoconfigure.web.servlet.WebMvcAutoConfiguration] is not eligible for getting processed by all BeanPostProcessors (for example: not eligible for auto-proxying) 2021-08-14 17:53:25.555 INFO 80884 --- [ main] trationDelegate$BeanPostProcessorChecker : Bean 'formContentFilter' of type [org.springframework.boot.web.servlet.filter.OrderedFormContentFilter] is not eligible for getting processed by all BeanPostProcessors (for example: not eligible for auto-proxying) 2021-08-14 17:53:25.573 INFO 80884 --- [ main] trationDelegate$BeanPostProcessorChecker : Bean 'server-org.springframework.boot.autoconfigure.web.ServerProperties' of type [org.springframework.boot.autoconfigure.web.ServerProperties] is not eligible for getting processed by all BeanPostProcessors (for example: not eligible for auto-proxying) 2021-08-14 17:53:25.575 INFO 80884 --- [ main] trationDelegate$BeanPostProcessorChecker : Bean 'org.springframework.boot.autoconfigure.web.servlet.HttpEncodingAutoConfiguration' of type [org.springframework.boot.autoconfigure.web.servlet.HttpEncodingAutoConfiguration] is not eligible for getting processed by all BeanPostProcessors (for example: not eligible for auto-proxying) 2021-08-14 17:53:25.576 INFO 80884 --- [ main] trationDelegate$BeanPostProcessorChecker : Bean 'characterEncodingFilter' of type [org.springframework.boot.web.servlet.filter.OrderedCharacterEncodingFilter] is not eligible for getting processed by all BeanPostProcessors (for example: not eligible for auto-proxying) 2021-08-14 17:53:25.601 INFO 80884 --- [ main] trationDelegate$BeanPostProcessorChecker : Bean 'org.apache.shiro.spring.config.web.autoconfigure.ShiroWebFilterConfiguration' of type [org.apache.shiro.spring.config.web.autoconfigure.ShiroWebFilterConfiguration$$EnhancerBySpringCGLIB$$2285dfd6] is not eligible for getting processed by all BeanPostProcessors (for example: not eligible for auto-proxying) 2021-08-14 17:53:25.615 INFO 80884 --- [ main] trationDelegate$BeanPostProcessorChecker : Bean 'globalFilters' of type [java.util.Collections$SingletonList] is not eligible for getting processed by all BeanPostProcessors (for example: not eligible for auto-proxying) 2021-08-1
发现这个信息一直在输出:
Bean ‘xxx’ of type [com.example.demo.business.rbac.user.service.impl.UserServiceImpl] is not eligible for getting processed by all BeanPostProcessors (for example: not eligible for auto-proxying)
中文描述
意思是:xxx这个bean不能被所有的BeanPostProcessors处理(比如:自动代理(即:AOP))
这个输出可能引起的问题
我们知道,Spring的很多逻辑是用AOP实现的,比较重要的一个就是:数据库的事务。如果事务不能被代理的话,那么Spring将无法控制事务(比如:提交、回滚)。
原因解析
简介
依赖了UserService的某个bean实现了BeanPostProcessor之类的接口,导致UserServiceImpl被提前注入,导致无法被AOP。
断点调试
1.打条件断点
在SpringBoot的代码中获得userServiceImpl这个bean的地方打断点,看是哪个特殊的bean最终依赖了userServiceImpl这个bean。
打条件断点:
我如何知道在哪里打断点的?
这个就要了解Bean的创建过程了,见:Spring-Bean生命周期-流程/原理 – 自学精灵
所以,本处的断点可以打在下边这些的任意一个方法里边:
- AbstractBeanFactory#getBean
- AbstractBeanFactory#doGetBean
- AbstractAutowireCapableBeanFactory#createBean
- AbstractAutowireCapableBeanFactory#doCreateBean
2.进入断点
在上边的箭头处沿着栈信息往前找,看它是如何依赖到UserServiceImpl的。
前边是bean的类型,后边是bean的名字。有的bean没类型(required为null),只有bean名字。 org.springframework.beans.factory.config.BeanPostProcessor(webMvcObjectMapperConfigurer) org.springframework.aop.Advisor(org.springframework.transaction.config.internalTransactionAdvisor) (org.springframework.transaction.annotation.ProxyTransactionManagementConfiguration) org.springframework.aop.Advisor(authorizationAttributeSourceAdvisor) (securityManager) (getDatabaseRealm) //这个是我代码中自定义的Realm的用@Bean注册时的方法名 (userServiceImpl)
一目了然了。我代码里边是webMvcObjectMapperConfigurer这个BeanPostProcessor的实现类最终依赖到了UserServiceImpl。它使UserServiceImpl提前被IOC,无法被AOP了。
注意
本处我的代码是webMvcObjectMapperConfigurer这个BeanPostProcessor的实现类最终依赖到了UserServiceImpl。
这个与个人的Shiro使用方式有关,我是在代码里提供了下边这个bean,所以才会这样
/** * 开启shiro aop注解支持. * 使用代理方式;所以需要开启代码支持; * * @param securityManager * @return */ @Bean public AuthorizationAttributeSourceAdvisor authorizationAttributeSourceAdvisor( SecurityManager securityManager) { AuthorizationAttributeSourceAdvisor authorizationAttributeSourceAdvisor = new AuthorizationAttributeSourceAdvisor(); authorizationAttributeSourceAdvisor.setSecurityManager(securityManager); return authorizationAttributeSourceAdvisor; }
如果提供了ShiroFilterFactoryBean这个bean,也会导致“is not eligible for getting processed by all BeanPostProcessors”这个问题,因为它也实现了BeanPostProcessor接口。
解决方案
方案1:延迟初始化
其他网址
Spring-BeanPostProcessor-注意问题/坑 – 自学精灵
Spring-延迟加载(@Lazy注解等)-使用/原理 – 自学精灵
简介
可以使用延迟初始化来解决。延迟初始化会在IOC的时候先给出一个代理类,IOC之后的AOP这个BeanPostProcessor会正常地给它处理。
具体做法
加一个注解即可:@Lazy。可以在两个地方加这个注解:字段、方法参数。
方案1:加到字段上
import org.springframework.context.annotation.Lazy; import org.apache.shiro.realm.AuthorizingRealm; public class DatabaseRealm extends AuthorizingRealm { @Lazy @Autowired private UserService userService; }
方案2:加到构造方法的参数上
import org.springframework.context.annotation.Lazy; import org.apache.shiro.realm.AuthorizingRealm; public class DatabaseRealm extends AuthorizingRealm { private UserService userService; public DatabaseRealm(@Lazy @Autowired UserService userService){ this.userService = userService; } }
修改之后的输出
我把业务有关的数据库Service都加上了@Lazy。就是这几个:UserService、OrderService、ProductService。
2021-08-14 20:03:12.810 INFO 8232 --- [ main] trationDelegate$BeanPostProcessorChecker : Bean 'org.apache.shiro.spring.boot.autoconfigure.ShiroBeanAutoConfiguration' of type [org.apache.shiro.spring.boot.autoconfigure.ShiroBeanAutoConfiguration$$EnhancerBySpringCGLIB$$a5a744cc] is not eligible for getting processed by all BeanPostProcessors (for example: not eligible for auto-proxying) 2021-08-14 20:03:12.833 INFO 8232 --- [ main] trationDelegate$BeanPostProcessorChecker : Bean 'org.apache.shiro.spring.boot.autoconfigure.ShiroAnnotationProcessorAutoConfiguration' of type [org.apache.shiro.spring.boot.autoconfigure.ShiroAnnotationProcessorAutoConfiguration$$EnhancerBySpringCGLIB$$a83a8371] is not eligible for getting processed by all BeanPostProcessors (for example: not eligible for auto-proxying) 2021-08-14 20:03:12.866 INFO 8232 --- [ main] trationDelegate$BeanPostProcessorChecker : Bean 'shiroConfig' of type [com.example.demo.config.shiro.ShiroConfig$$EnhancerBySpringCGLIB$$4242a0c5] is not eligible for getting processed by all BeanPostProcessors (for example: not eligible for auto-proxying) 2021-08-14 20:03:13.297 INFO 8232 --- [ main] trationDelegate$BeanPostProcessorChecker : Bean 'hashedCredentialsMatcher' of type [org.apache.shiro.authc.credential.HashedCredentialsMatcher] is not eligible for getting processed by all BeanPostProcessors (for example: not eligible for auto-proxying) 2021-08-14 20:03:13.315 INFO 8232 --- [ main] trationDelegate$BeanPostProcessorChecker : Bean 'getDatabaseRealm' of type [com.example.demo.config.shiro.realm.DatabaseRealm] is not eligible for getting processed by all BeanPostProcessors (for example: not eligible for auto-proxying) 2021-08-14 20:03:13.319 INFO 8232 --- [ main] trationDelegate$BeanPostProcessorChecker : Bean 'sessionManager' of type [org.apache.shiro.web.session.mgt.DefaultWebSessionManager] is not eligible for getting processed by all BeanPostProcessors (for example: not eligible for auto-proxying) 2021-08-14 20:03:13.321 INFO 8232 --- [ main] trationDelegate$BeanPostProcessorChecker : Bean 'securityManager' of type [org.apache.shiro.web.mgt.DefaultWebSecurityManager] is not eligible for getting processed by all BeanPostProcessors (for example: not eligible for auto-proxying) 2021-08-14 20:03:13.326 INFO 8232 --- [ main] trationDelegate$BeanPostProcessorChecker : Bean 'authorizationAttributeSourceAdvisor' of type [org.apache.shiro.spring.security.interceptor.AuthorizationAttributeSourceAdvisor] is not eligible for getting processed by all BeanPostProcessors (for example: not eligible for auto-proxying) 2021-08-14 20:03:13.342 INFO 8232 --- [ main] trationDelegate$BeanPostProcessorChecker : Bean 'eventBus' of type [org.apache.shiro.event.support.DefaultEventBus] is not eligible for getting processed by all BeanPostProcessors (for example: not eligible for auto-proxying) 2021-08-14 20:03:13.349 INFO 8232 --- [ main] trationDelegate$BeanPostProcessorChecker : Bean 'shiroFilterChainDefinition' of type [org.apache.shiro.spring.web.config.DefaultShiroFilterChainDefinition] is not eligible for getting processed by all BeanPostProcessors (for example: not eligible for auto-proxying) 2021-08-14 20:03:13.352 INFO 8232 --- [ main] trationDelegate$BeanPostProcessorChecker : Bean 'requestContextFilter' of type [org.springframework.boot.web.servlet.filter.OrderedRequestContextFilter] is not eligible for getting processed by all BeanPostProcessors (for example: not eligible for auto-proxying) 2021-08-14 20:03:13.356 INFO 8232 --- [ main] trationDelegate$BeanPostProcessorChecker : Bean 'org.springframework.boot.autoconfigure.web.servlet.WebMvcAutoConfiguration' of type [org.springframework.boot.autoconfigure.web.servlet.WebMvcAutoConfiguration] is not eligible for getting processed by all BeanPostProcessors (for example: not eligible for auto-proxying) 2021-08-14 20:03:13.358 INFO 8232 --- [ main] trationDelegate$BeanPostProcessorChecker : Bean 'formContentFilter' of type [org.springframework.boot.web.servlet.filter.OrderedFormContentFilter] is not eligible for getting processed by all BeanPostProcessors (for example: not eligible for auto-proxying) 2021-08-14 20:03:13.385 INFO 8232 --- [ main] trationDelegate$BeanPostProcessorChecker : Bean 'server-org.springframework.boot.autoconfigure.web.ServerProperties' of type [org.springframework.boot.autoconfigure.web.ServerProperties] is not eligible for getting processed by all BeanPostProcessors (for example: not eligible for auto-proxying) 2021-08-14 20:03:13.387 INFO 8232 --- [ main] trationDelegate$BeanPostProcessorChecker : Bean 'org.springframework.boot.autoconfigure.web.servlet.HttpEncodingAutoConfiguration' of type [org.springframework.boot.autoconfigure.web.servlet.HttpEncodingAutoConfiguration] is not eligible for getting processed by all BeanPostProcessors (for example: not eligible for auto-proxying) 2021-08-14 20:03:13.388 INFO 8232 --- [ main] trationDelegate$BeanPostProcessorChecker : Bean 'characterEncodingFilter' of type [org.springframework.boot.web.servlet.filter.OrderedCharacterEncodingFilter] is not eligible for getting processed by all BeanPostProcessors (for example: not eligible for auto-proxying) 2021-08-14 20:03:13.402 INFO 8232 --- [ main] trationDelegate$BeanPostProcessorChecker : Bean 'org.apache.shiro.spring.config.web.autoconfigure.ShiroWebFilterConfiguration' of type [org.apache.shiro.spring.config.web.autoconfigure.ShiroWebFilterConfiguration$$EnhancerBySpringCGLIB$$fcae0a6d] is not eligible for getting processed by all BeanPostProcessors (for example: not eligible for auto-proxying) 2021-08-14 20:03:13.410 INFO 8232 --- [ main] trationDelegate$BeanPostProcessorChecker : Bean 'globalFilters' of type [java.util.Collections$SingletonList] is not eligible for getting processed by all BeanPostProcessors (for example: not eligible for auto-proxying)
可以看到,这几个Service的输出就没有了。
但是,还有其他的bean会报这个问题。报就报吧,只要他没影响到功能就行。
方案2:@Role(BeanDefinition.ROLE_INFRASTRUCTURE)
简介
方案说明
在Bean的声明上加个注解:@Role(BeanDefinition.ROLE_INFRASTRUCTURE)
表明这个bean是完全后台模式,不需要被代理。
需要注意的是,我们的Realm需要操作数据库,它里边依赖的Service(例如UserService)仍然需要被代理。所以,上边“方案1”的延迟初始化仍然需要加到UserService等Service上。
原理
Spring 容器初始化时会在refresh方法中执行 registerBeanPostProcessors(beanFactory);
此方法为容器增加了一个BeanPostProcessorChecker这个BeanPostProcessor,它会记录下当前的BeanPostProcessor数量。方法位置是:org.springframework.context.support.PostProcessorRegistrationDelegate.BeanPostProcessorChecker#postProcessAfterInitialization
代码如下:
@Override public Object postProcessAfterInitialization(Object bean, String beanName) { if (!(bean instanceof BeanPostProcessor) && !isInfrastructureBean(beanName) && this.beanFactory.getBeanPostProcessorCount() < this.beanPostProcessorTargetCount) { if (logger.isInfoEnabled()) { logger.info("Bean '" + beanName + "' of type [" + bean.getClass().getName() + "] is not eligible for getting processed by all BeanPostProcessors " + "(for example: not eligible for auto-proxying)"); } } return bean; }
满足了三个条件才会打印这个日志,
1. bean 没有实现BeanPostProcesor
2. 不是 isInfrastructureBean,
3. 之前记录的BeanPostProcess数量少于当前的数量。
测试
在Shiro的总配置类上的所有Bean上都加上@Role(BeanDefinition.ROLE_INFRASTRUCTURE)。
代码示例:
package com.example.demo.config.shiro; import com.example.demo.common.constant.WhiteList; import com.example.demo.config.shiro.filter.JwtFilter; import com.example.demo.config.shiro.realm.AccountRealm; import org.apache.shiro.authc.credential.HashedCredentialsMatcher; import org.apache.shiro.mgt.DefaultSessionStorageEvaluator; import org.apache.shiro.mgt.DefaultSubjectDAO; import org.apache.shiro.mgt.SecurityManager; import org.apache.shiro.spring.security.interceptor.AuthorizationAttributeSourceAdvisor; import org.apache.shiro.spring.web.ShiroFilterFactoryBean; import org.apache.shiro.spring.web.config.DefaultShiroFilterChainDefinition; import org.apache.shiro.spring.web.config.ShiroFilterChainDefinition; import org.apache.shiro.web.filter.authc.AuthenticatingFilter; import org.apache.shiro.web.mgt.DefaultWebSecurityManager; import org.springframework.aop.framework.autoproxy.DefaultAdvisorAutoProxyCreator; import org.springframework.beans.factory.config.BeanDefinition; import org.springframework.context.annotation.Bean; import org.springframework.context.annotation.Configuration; import org.springframework.context.annotation.Role; import javax.servlet.Filter; import java.util.LinkedHashMap; import java.util.Map; @Configuration @Role(BeanDefinition.ROLE_INFRASTRUCTURE) public class ShiroConfig { @Bean @Role(BeanDefinition.ROLE_INFRASTRUCTURE) public ShiroFilterChainDefinition shiroFilterChainDefinition() { DefaultShiroFilterChainDefinition chainDefinition = new DefaultShiroFilterChainDefinition(); chainDefinition.addPathDefinition("/login", "anon"); WhiteList.ALL.forEach(str -> { chainDefinition.addPathDefinition(str, "anon"); }); // all other paths require a logged in user chainDefinition.addPathDefinition("/**", "jwt"); return chainDefinition; } /** * 设置过滤器,将自定义的Filter加入。 */ @Bean("shiroFilterFactoryBean") @Role(BeanDefinition.ROLE_INFRASTRUCTURE) public ShiroFilterFactoryBean shiroFilterFactoryBean(SecurityManager securityManager) { ShiroFilterFactoryBean factoryBean = new ShiroFilterFactoryBean(); // 登录的地址 factoryBean.setLoginUrl("/login"); // 登录成功后要跳转的地址 // factoryBean.setSuccessUrl("/index"); // 未授权地址 // factoryBean.setUnauthorizedUrl("/unauthorized"); factoryBean.setSecurityManager(securityManager); Map<String, Filter> filterMap = factoryBean.getFilters(); filterMap.put("jwt", new JwtFilter()); factoryBean.setFilters(filterMap); factoryBean.setFilterChainDefinitionMap(shiroFilterChainDefinition().getFilterChainMap()); return factoryBean; } @Bean @Role(BeanDefinition.ROLE_INFRASTRUCTURE) public DefaultWebSecurityManager securityManager() { DefaultSubjectDAO subjectDAO = new DefaultSubjectDAO(); DefaultSessionStorageEvaluator defaultSessionStorageEvaluator = new DefaultSessionStorageEvaluator(); // 关闭shiro自带的session。这样不能通过session登录shiro,后面将采用jwt凭证登录。 // 见:http://shiro.apache.org/session-management.html#SessionManagement-DisablingSubjectStateSessionStorage defaultSessionStorageEvaluator.setSessionStorageEnabled(false); subjectDAO.setSessionStorageEvaluator(defaultSessionStorageEvaluator); DefaultWebSecurityManager securityManager = new DefaultWebSecurityManager(); securityManager.setRealm(getDatabaseRealm()); securityManager.setSubjectDAO(subjectDAO); return securityManager; } @Bean @Role(BeanDefinition.ROLE_INFRASTRUCTURE) public AccountRealm getDatabaseRealm() { return new AccountRealm(); } /** * setUsePrefix(true)用于解决一个奇怪的bug。如下: * 在引入spring aop的情况下,在@Controller注解的类的方法中加入@RequiresRole等 * shiro注解,会导致该方法无法映射请求,导致返回404。加入这项配置能解决这个bug。 */ @Bean @Role(BeanDefinition.ROLE_INFRASTRUCTURE) public static DefaultAdvisorAutoProxyCreator getDefaultAdvisorAutoProxyCreator(){ DefaultAdvisorAutoProxyCreator defaultAdvisorAutoProxyCreator=new DefaultAdvisorAutoProxyCreator(); defaultAdvisorAutoProxyCreator.setUsePrefix(true); return defaultAdvisorAutoProxyCreator; } }
启动结果
. ____ _ __ _ _ /\\ / ___'_ __ _ _(_)_ __ __ _ \ \ \ \ ( ( )\___ | '_ | '_| | '_ \/ _` | \ \ \ \ \\/ ___)| |_)| | | | | || (_| | ) ) ) ) ' |____| .__|_| |_|_| |_\__, | / / / / =========|_|==============|___/=/_/_/_/ :: Spring Boot :: (v2.3.8.RELEASE) 2022-05-18 19:16:52.898 INFO 4824 --- [ main] com.example.demo.ShiroApplication : Starting ShiroApplication on DESKTOP-QI6B9ME with PID 4824 (E:\work\Idea_proj\shiro\shiro_3_jwt\target\classes started by Liu in E:\work\Idea_proj\shiro\shiro_3_jwt) 2022-05-18 19:16:52.901 INFO 4824 --- [ main] com.example.demo.ShiroApplication : No active profile set, falling back to default profiles: default 2022-05-18 19:16:53.884 INFO 4824 --- [ main] trationDelegate$BeanPostProcessorChecker : Bean 'org.apache.shiro.spring.boot.autoconfigure.ShiroBeanAutoConfiguration' of type [org.apache.shiro.spring.boot.autoconfigure.ShiroBeanAutoConfiguration$$EnhancerBySpringCGLIB$$88a9810a] is not eligible for getting processed by all BeanPostProcessors (for example: not eligible for auto-proxying) 2022-05-18 19:16:53.972 INFO 4824 --- [ main] trationDelegate$BeanPostProcessorChecker : Bean 'org.apache.shiro.spring.boot.autoconfigure.ShiroAnnotationProcessorAutoConfiguration' of type [org.apache.shiro.spring.boot.autoconfigure.ShiroAnnotationProcessorAutoConfiguration$$EnhancerBySpringCGLIB$$8b3cbfaf] is not eligible for getting processed by all BeanPostProcessors (for example: not eligible for auto-proxying) 2022-05-18 19:16:54.477 INFO 4824 --- [ main] trationDelegate$BeanPostProcessorChecker : Bean 'authorizationAttributeSourceAdvisor' of type [org.apache.shiro.spring.security.interceptor.AuthorizationAttributeSourceAdvisor] is not eligible for getting processed by all BeanPostProcessors (for example: not eligible for auto-proxying) 2022-05-18 19:16:54.489 INFO 4824 --- [ main] trationDelegate$BeanPostProcessorChecker : Bean 'eventBus' of type [org.apache.shiro.event.support.DefaultEventBus] is not eligible for getting processed by all BeanPostProcessors (for example: not eligible for auto-proxying) 2022-05-18 19:16:54.702 INFO 4824 --- [ main] o.s.b.w.embedded.tomcat.TomcatWebServer : Tomcat initialized with port(s): 8080 (http) 2022-05-18 19:16:54.711 INFO 4824 --- [ main] o.apache.catalina.core.StandardService : Starting service [Tomcat] 2022-05-18 19:16:54.711 INFO 4824 --- [ main] org.apache.catalina.core.StandardEngine : Starting Servlet engine: [Apache Tomcat/9.0.41] 2022-05-18 19:16:54.817 INFO 4824 --- [ main] o.a.c.c.C.[Tomcat].[localhost].[/] : Initializing Spring embedded WebApplicationContext 2022-05-18 19:16:54.817 INFO 4824 --- [ main] w.s.c.ServletWebServerApplicationContext : Root WebApplicationContext: initialization completed in 1872 ms Logging initialized using 'class org.apache.ibatis.logging.stdout.StdOutImpl' adapter. Property 'mapperLocations' was not specified. _ _ |_ _ _|_. ___ _ | _ | | |\/|_)(_| | |_\ |_)||_|_\ / | 3.4.3.1 2022-05-18 19:16:56.483 INFO 4824 --- [ main] o.s.s.concurrent.ThreadPoolTaskExecutor : Initializing ExecutorService 'applicationTaskExecutor' 2022-05-18 19:16:56.764 INFO 4824 --- [ main] o.s.b.w.embedded.tomcat.TomcatWebServer : Tomcat started on port(s): 8080 (http) with context path '' 2022-05-18 19:16:56.947 INFO 4824 --- [ main] com.example.demo.ShiroApplication : Started ShiroApplication in 4.399 seconds (JVM running for 5.471)
可见,“is not eligible for getting processed by all BeanPostProcessors”警告已经少了很多,但还是有4个类的警告:ShiroBeanAutoConfiguration、ShiroAnnotationProcessorAutoConfiguration、AuthorizationAttributeSourceAdvisor、DefaultEventBus。
上边这4个是Shiro包里边的类,我们无法处理。
思考
如何完全去掉“is not eligible for getting processed by all BeanPostProcessors”这个输出?
很不幸,没有办法。Shiro它在关键的bean处实现了BeanPostProcessor接口,它又依赖了其他东西,就会导致其他东西提前IOC,无法AOP。
一个很好的权限框架应该是这样的:
- 可以方便配置使用session或者token
- 可以方便配置session或token的超时时间
- 不实现BeanPostProcessor
- 提供无需身份认证的注解,这个注解可以加到方法或者类上
- 默认支持主流的缓存技术:Redis、Memcache、单机版。而且可配置、可自定义读写缓存的逻辑
- 支持前后端一体的和前后端分离的场景,可以通过配置来切换。
- 比如:我想前后端分离,就用不到shiro里边的loginUrl、successUrl、unauthorizedUrl
请先
!