Spring mvc 中有关 Shiro 1.2.3 配置问题

王朝学院·作者佚名  2016-05-29
窄屏简体版  字體: 小  |  中  |  大  |  超大  

SPRing mvc 中有关 Shiro 1.2.3 配置问题Spring 版本:3.2.x, 4.0.x

【问题说明】

首先介绍下配置出错情况:

(1)项目中,Spring3 and Spring4 的 applicationContext.xml aop 配置如下:

... ... <aop:aspectj-autoproxy expose-proxy="true"/> <tx:annotation-driven transaction-manager="transactionManager"/> <tx:advice id="txAdvice" transaction-manager="transactionManager"> <tx:attributes> <tx:method name="save*" propagation="REQUIRED" /> <tx:method name="add*" propagation="REQUIRED" /> <tx:method name="create*" propagation="REQUIRED" /> <tx:method name="insert*" propagation="REQUIRED" /> <tx:method name="update*" propagation="REQUIRED" /> <tx:method name="del*" propagation="REQUIRED" /> <tx:method name="get*" propagation="REQUIRED" read-only="true" /> <tx:method name="find*" propagation="REQUIRED" read-only="true" /> <tx:method name="query*" propagation="REQUIRED" read-only="true" /> <tx:method name="*" read-only="true"/> </tx:attributes> </tx:advice> <aop:config expose-proxy="true"> <!-- 只对业务逻辑层实施事务 --> <aop:pointcut id="txPointcut" expression="execution(* com.app..service..*.*(..))" /> <aop:advisor advice-ref="txAdvice" pointcut-ref="txPointcut"/> </aop:config>... ...

未加入 Shiro 之前,所有 applicationContext 的 getBean(...) 方法能正常获取到相应对象实例。 调用getBeanDefinitionNames()输出的 Beans 如下:

Bean Name

Bean Class

userDaoImpl

class com.app.dao.impl.UserDaoImpl

resourceServiceImpl

class com.app.service.impl.ResourceServiceImpl$$EnhancerBySpringCGLIB$$4ddf6901

roleServiceImpl

class com.app.service.impl.RoleServiceImpl

userServiceImpl

class com.app.service.impl.UserServiceImpl$$EnhancerBySpringCGLIB$$e7bcd944

以上 bean 都采用 @Repository 或@Service 的注解方式。

注意标红Class名称,这是因为被 CGLIB 动态代理。

(2)根据 Shiro 示例,新增配置文件 applicationContext-security.xml,然后配置Shiro 如下:

... ... <bean id="securityManager" class="org.apache.shiro.web.mgt.DefaultWebSecurityManager"> <property name="realm" ref="myRealm"/> </bean> <bean id="lifecycleBeanPostProcessor" class="org.apache.shiro.spring.LifecycleBeanPostProcessor"/> <bean class="org.springframework.aop.framework.autoproxy.DefaultAdvisorAutoProxyCreator" depends-on="lifecycleBeanPostProcessor"> </bean> <bean class="org.apache.shiro.spring.security.interceptor.AuthorizationAttributeSourceAdvisor"> <property name="securityManager" ref="securityManager"/> </bean> <bean id="formAuthenticationFilter" class="org.apache.shiro.web.filter.authc.FormAuthenticationFilter"/>... ...

加入 Shiro 之后,发现有些地方 getBean(...) 出错,调用getBeanDefinitionNames()输出的 Beans 如下:

Bean Name

Bean Class

userDaoImpl

class com.app.dao.impl.UserDaoImpl

resourceServiceImpl

class $Proxy38

roleServiceImpl

class com.app.service.impl.RoleServiceImpl

userServiceImpl

class $Proxy32

可以注意到标红Class名称,这是由于配置 DefaultAdvisorAutoProxyCreator,又被 JDK 动态二次代理。

【解决办法】

两次都以 CGLIB 动态代理。在 AOP 配置加上proxy-target-class 属性,值为 true。具体如下:

(1)在 applicationContext.xml 中配置

... ... <aop:config expose-proxy="true" proxy-target-class="true"> <!-- 只对业务逻辑层实施事务 --> <aop:pointcut id="txPointcut" expression="execution(* com.app..service..*.*(..))" /> <aop:advisor advice-ref="txAdvice" pointcut-ref="txPointcut"/> </aop:config>... ...

(2)在 applicationContext-security.xml 配置 Shiro

... ... <bean class="org.springframework.aop.framework.autoproxy.DefaultAdvisorAutoProxyCreator" depends-on="lifecycleBeanPostProcessor"> <property name="proxyTargetClass" value="true"/> </bean>... ...

修改完成后,重新运行程序,getBean 恢复正常。

【参考资料】

spring的二次代理原因及如何排查 http://jinnianshilongnian.iteye.com/blog/1894465

 
 
免责声明:本文为网络用户发布,其观点仅代表作者个人观点,与本站无关,本站仅提供信息存储服务。文中陈述内容未经本站证实,其真实性、完整性、及时性本站不作任何保证或承诺,请读者仅作参考,并请自行核实相关内容。
 
© 2005- 王朝網路 版權所有 導航