启用Spring AOP时遭遇BeanNotOfRequiredTypeException问题求助
我之前在整合Apache Shiro和Spring MVC实现权限校验时,也碰到过一模一样的BeanNotOfRequiredTypeException异常,大概率是Shiro的AOP代理和Spring自身的代理机制冲突导致的类型不匹配问题。下面是我亲测有效的排查和解决步骤:
1. 先确认版本兼容性
第一步一定要检查你的Shiro版本和Spring MVC版本是否匹配:
- 比如Shiro 1.7.x系列对应Spring 5.x版本,Shiro 1.10+可以兼容Spring 6.x;
- 版本不兼容会导致底层代理逻辑出现各种奇怪的类型转换错误,这是最容易被忽略的点。
2. 调整DefaultAdvisorAutoProxyCreator配置,强制统一代理类型
默认情况下DefaultAdvisorAutoProxyCreator可能会混合使用JDK动态代理和CGLIB代理,这很容易引发类型不匹配。你可以给它添加proxyTargetClass=true属性,强制使用CGLIB代理:
<bean id="annotationProxy" class="org.springframework.aop.framework.autoproxy.DefaultAdvisorAutoProxyCreator" depends-on="lifecycleBeanPostProcessor"> <property name="proxyTargetClass" value="true"/> </bean>
3. 补全AuthorizationAttributeSourceAdvisor的完整配置
你的配置里AuthorizationAttributeSourceAdvisor没写完,必须确保这个Bean正确关联Shiro的securityManager,否则注解校验根本无法生效,还可能触发异常:
<bean class="org.apache.shiro.spring.security.interceptor.AuthorizationAttributeSourceAdvisor"> <property name="securityManager" ref="securityManager"/> </bean>
4. 排查项目中是否存在其他AOP配置冲突
如果你的项目里已经配置了Spring自身的AOP(比如<aop:aspectj-autoproxy/>),这时候和Shiro的DefaultAdvisorAutoProxyCreator会产生代理冲突:
- 解决办法二选一:
- 移除Spring的
<aop:aspectj-autoproxy/>配置,完全用Shiro的AOP代理来处理; - 给
<aop:aspectj-autoproxy/>也加上proxy-target-class="true",保持和Shiro代理方式一致:<aop:aspectj-autoproxy proxy-target-class="true"/>
- 移除Spring的
5. 检查Bean注入的类型匹配
如果你的项目里用了JDK动态代理(没开CfemsowerynA
部分看 used顺接维护会Ot把控部分,哦不对,是没开CGLIB的情况下),注入Bean时一定要用接口类型而不是实现类类型,否则会出现类型转换失败的异常。当然更省心的方式是直接开CGLIB代理(步骤2的配置),就不用纠结接口和实现类的问题了。
最后给你一个完整的Shiro注解权限校验的AOP配置示例,你可以参考调整:
<!-- Shiro生命周期处理器,必须配置 --> <bean id="lifecycleBeanPostProcessor" class="org.apache.shiro.spring.LifecycleBeanPostProcessor"/> <!-- 启用Shiro注解支持的AOP自动代理 --> <bean id="defaultAdvisorAutoProxyCreator" class="org.springframework.aop.framework.autoproxy.DefaultAdvisorAutoProxyCreator" depends-on="lifecycleBeanPostProcessor"> <property name="proxyTargetClass" value="true"/> </bean> <!-- Shiro权限注解的Advisor,负责解析@RequiresPermissions等注解 --> <bean class="org.apache.shiro.spring.security.interceptor.AuthorizationAttributeSourceAdvisor"> <property name="securityManager" ref="securityManager"/> </bean>
内容的提问来源于stack exchange,提问作者Bibek Khadka

