引言

    在初步使用Spring MVC框架中使用切面的时候可能会遇到AOP对controller层切面无效。这其实是spring容器的原因。下面将详细讲解。切面配置没有问题的情况下,junit单元测试调用controller里面的方法,可以触发切点,实现切面编程。但是web部署到tomcat后,直接url访问触发切点失败!


问题起因

经查看,项目中有两个配置文件。
  • spring-mvc.xml
  • applicationContext.xml 
applicationContext.xml 部分代码:
<!-- 自动扫描项目下面的包 ,将带有注解的类 纳入spring容器管理   扫描service、dao -->
<context:component-scan base-package="com.test"></context:component-scan>
<!-- 配置使Spring采用CGLIB代理 -->
<aop:aspectj-autoproxy proxy-target-class="true" />
spring-mvc.xml配置代码:
<!-- 默认的注解映射的支持 -->
<mvc:annotation-driven />

<!-- 自动扫描该包,使SpringMVC认为包下用了@controller注解的类是控制器 -->
<context:component-scan base-package="com.test.controller" />

其实通过上一篇转载的Spring Context 与Spring MVC Context 博客中可以知道,spring 和spring mvc是两个容器,且spring mvc是spring的子容器。上面的启用代理的配置在父级spring容器中,由于spring 容器中,子容器可以访问父级容器资源但是父级容器无法访问子容器。所以导致了controller的AOP无效.

解决办法:


将以下配置AOP注解启用代理的片段代码移入spring-mvc.xml配置文件中,这样AOP就可以代理两个容器所有资源。
<!-- 配置使Spring采用CGLIB代理 -->
<aop:aspectj-autoproxy proxy-target-class="true" />