Spring AOP无法拦截Controller中的方法
想使用AOP Annotation配置Spring MVC的Controller进行拦截, 发现无法拦截Controller的方法, 却可以拦截Service层的方法.
一开始:
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层的自动扫描配置.
代码2:spring-mvc.xml <context:component-scan base-package="com.hodc.sdk.controller" />
增强代码为如下:

代码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; }

需要被拦截的方法如下:

代码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写法也没有作用.
参照http://stackoverflow.com/questions/17834958/spring-aop-is-not-working-in-with-mvc-structure?rq=1
因为Spring的Bean扫描和Spring-MVC的Bean扫描是分开的, 两者的Bean位于两个不同的Application, 而且Spring-MVC的Bean扫描要早于Spring的Bean扫描, 所以当Controller Bean生成完成后, 再执行Spring的Bean扫描,Spring会发现要被AOP代理的Controller Bean已经在容器中存在, 配置AOP就无效了.
同样这样的情况也存在于数据库事务中, 如果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都是有效的,但是第一种是最精确的.
Spring AOP无法拦截Controller中的方法的更多相关文章
- Spring的Aspect切面类不能拦截Controller中的方法
根本原因在于<aop:aspectj-autoproxy />这句话是在spring的配置文件内,还是在springmvc的配置文件内.如果是在spring的配置文件内,则@Control ...
- spingAOP在springMVC中的使用(我用在拦截controller中的方法。主要用于登录控制)
首先截取了网上的一张配置execution的图片 我在项目中关于aop的配置:如果拦截controller的方法,需要在spring-mvc.xml文件中加入(如果在spring.xml中加入则无法拦 ...
- spring aop无法拦截类内部的方法调用
1.概念 拦截器的实现原理就是动态代理,实现AOP机制.Spring 的代理实现有两种:一是基于 JDK Dynamic Proxy 技术而实现的:二是基于 CGLIB 技术而实现的.如果目标对象实现 ...
- Spring AOP无法拦截Controller的原因
因为Spring的Bean扫描和Spring-MVC的Bean扫描是分开的, 两者的Bean位于两个不同的Application, 而且Spring-MVC的Bean扫描要早于Spring的Bean扫 ...
- Spring AOP无法拦截Controller
参考@参考文章中的评论 首先,应该打开aop代理 <aop:aspectj-autoproxy proxy-target-class="true"/> 其次,应该讲ao ...
- Spring AOP获取拦截方法的参数名称跟参数值
注意:这种方式需要JDK1.8版本支持 开始:http://www.cnblogs.com/wing7319/p/9592184.html 1.aop配置: <aop:aspectj-autop ...
- Spring AOP开发时如何得到某个方法内调用的方法的代理对象?
Spring AOP开发时如何得到某个方法内调用的方法的代理对象? 问题阅读起来拗口,看代码 在方法中调用其他方法很常见,也经常使用,如果在一个方法内部调用其他方法,比如 public class U ...
- ASP.NET MVC4在View中调用当前Controller中的方法
调用当前Controller中的方法 @{ ((HomeController)ViewContext.Controller).Method1(); } 调用静态方法 @{ SomeClass.Meth ...
- Spring AOP不拦截从对象内部调用的方法原因
拦截器的实现原理很简单,就是动态代理,实现AOP机制.当外部调用被拦截bean的拦截方法时,可以选择在拦截之前或者之后等条件执行拦截方法之外的逻辑,比如特殊权限验证,参数修正等操作. 但是最近在项目中 ...
随机推荐
- Django的模板系统
一.语法 关于模板渲染只需要记住两种特殊符号(语法): {{ }} 和 {% %} (变量相关用{{ }} 逻辑相关用{% %}) 二.变量 在Django的模板语言中按照{{ 变量名 }}来使用 ...
- 什么是CSR以及CSR的作用和生成
什么是CSR以及CSR的作用和生成 来源:https://www.trustasia.com/news-201801-what-is-the-role-and-generation-of-csr-an ...
- LEDAPS1.3.0版本移植到windows平台----HuCal定标模块
这个是2012年左右放在百度空间的,谁知百度空间关闭...转移到博客园. 最近项目用到3.1.2版本的LEDAPS,新版本的使用情况会在后续文章中慢慢丰富. HuCal是将LEDAPS项目中的TM/E ...
- Java map 详解
Map 提供了一个更通用的元素存储方法.Map 集合类用于存储元素对(称作“键”和“值”),其中每个键映射到一个值. 初始化一个集合: Map<String, String> map = ...
- JHipster开发环境安装
本文演示如何在CentOS7上安装Jhipster以及其依赖组件. 这里采用官方推荐的Yarn安装方法,操作系统版本为CentOS 7.4. 1 安装JDK 推荐版本:OpenJDK 1.8.0-64 ...
- Docker Data Center系列(五)- 使用自定义的TLS安全认证
本系列文章演示如何搭建一个mini的云平台和DevOps实践环境. 基于这套实践环境,可以部署微服务架构的应用栈,演练提升DevOps实践能力. 1 名词说明 CSR: Certificate Sig ...
- 产品经理说| AIOps 让告警变得更智能 (下)
AIOps 人工智能和IT运营支撑 Ops 之间的故事,愈演愈烈,已经成为当今运维圈的热门话题,我打算从2篇文档分享我们在 AIOps 上一些探索和实践.(上篇)主要介绍了为什么事件(告警)处理需要 ...
- Scrapy代码实战
1.Spider爬虫代码 # -*- coding: utf-8 -*- import scrapy from yszd.items import YszdItem class YszdSpiderS ...
- 在Xshell 6开NumLock时按小键盘上的数字键并不能输入数字
小键盘问题 在Xshell 6上用vi的时候,开NumLock时按小键盘上的数字键并不能输入数字,而是出现一个字母然后换行(实际上是命令模式上对应上下左右的键).解决方法 选项Terminal-> ...
- MySQL多表更新的一个坑
简述 MySQL支持update t1,t2 set t1.a=2;这种语法,别的关系数据库例如oracle和sql server都不支持.这种语法有时候写起来挺方便,但他有一个坑. 测试脚本 dro ...