想使用AOP Annotation配置Spring MVC的Controller进行拦截, 发现没法拦截Controller的方法, 却能够拦截Service层的方法.web
一开始:spring
Spring的配置文件application.xml包含了 开启AOP自动代理,Service扫描配置,以及Aspect的自动扫描配置数据库
代码1:application.xml <aop:aspectj-autoproxy/> <context:component-scan base-package="com.example.sdk.service"> <context:component-scan base-package="com.hodc.sdk.aspect"/>
Spring MVC的配置文件spring-mvc.xml主要内容是Controller层的自动扫描配置.json
代码2:spring-mvc.xml <context:component-scan base-package="com.hodc.sdk.controller" />
加强代码为以下:spring-mvc
代码3 全限定名:com.example.sdk.aspect.ControllerAspect @Component @Aspect public class ControllerAspect { @Around(value = "execution(* com.hodc.sdk.controller.json.hadoop.HadoopClusterManage.*JsonWithException(..))") //1 // @Around(value = "within(@org.springframework.stereotype.Controller *)") //2 // @Around(value = "execution(* org.springframework.web.servlet.mvc.annotation.AnnotationMethodHandlerAdapter.handle(..))") //3 public Object test(ProceedingJoinPoint joint) { Result result = new Result(); System.out.println("in aspect"); result = (Result) joint.proceed(); return result; }
须要被拦截的方法以下:mvc
代码4 全限定名: com.example.sdk.controller.HadoopClusterManage#listVirtualHiveDBSJsonWithException @RequestMapping(value = "listVirtualHiveDBS.do", produces = "application/json") public @ResponseBody Result listVirtualHiveDBSJsonWithException(@RequestParam("clusterId") int clusterId) { Result result = new Result(); List<Db> dbs = syncServiceForWeb.listVirtualHiveDBS(clusterId); result.setData(dbs); return result; }
发现这样配置并无用, 这个方法没法被拦截, 参照网上搜索的结果, 将@Around的PointCut改为代码3中2,3写法也没有做用.app
参照http://stackoverflow.com/questions/17834958/spring-aop-is-not-working-in-with-mvc-structure?rq=1oop
由于Spring的Bean扫描和Spring-MVC的Bean扫描是分开的, 二者的Bean位于两个不一样的Application, 并且Spring-MVC的Bean扫描要早于Spring的Bean扫描, 因此当Controller Bean生成完成后, 再执行Spring的Bean扫描,Spring会发现要被AOP代理的Controller Bean已经在容器中存在, 配置AOP就无效了.spa
一样这样的状况也存在于数据库事务中, 若是Service的Bean扫描配置在spring-mvc.xml中, 而数据库事务管理器配置在application.xml中, 会致使数据库事务失效, 原理同样.代理
因此这里 ,咱们须要把AOP放置在Controller扫描配置的文件中.
Spring的配置文件application.xml包含了 开启AOP自动代理,Service扫描配置, 如今只包含了service的自动扫描配置
代码5:application.xml <context:component-scan base-package="com.example.sdk.service">
Spring MVC的配置文件spring-mvc.xml主要内容是Controller层的自动扫描配置,添加了开启AOP自动代理,以及Aspect的自动扫描配置
代码6:spring-mvc.xml <aop:aspectj-autoproxy/> <context:component-scan base-package="com.hodc.sdk.aspect"/> <context:component-scan base-package="com.hodc.sdk.controller" />
这样配置状况下代码3的3种pointcut都是有效的,可是第一种是最精确的.