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的拦截方法时,可以选择在拦截之前或者之后等条件执行拦截方法之外的逻辑,比如特殊权限验证,参数修正等操作. 但是最近在项目中 ...
随机推荐
- H5和PC实现点击复制当前文字的功能,兼容ios,安卓
<!DOCTYPE html> <html lang="en"> <head> <meta charset="UTF-8&quo ...
- 《从零开始学习jQuery》:用jQuery操作元素的属性与样式
元素属性和Dom属性简介 对于下面这样一个标签元素: <img id='img' src="1.jpg" alt='1' class="imgs"> ...
- 照葫芦画瓢系列之Java --- Maven的集成和使用
一.和Eclipse的集成 1.添加Maven 在windows--> preferences中找到maven选项,如下图: 如果没有上图的Name为apache-maven-3.5.2的项,则 ...
- iOS----------导航栏的正确隐藏方式
第一种做法 -注意这里一定要用动画的方式隐藏导航栏,这样在使用滑动返回手势的时候效果最好,和上面动图一致.这样做有一个缺点就是在切换tabBar的时候有一个导航栏向上消失的动画. - (void)vi ...
- Struts2.5学习笔记----org.apache.struts2.dispatcher.ng.filter.StrutsPrepareAndExecuteFilter报错
Struts2.3升级到struts2.5后报错 <filter> <filter-name>struts2</filter-name> <filter-cl ...
- C# 反射给对象赋值遇到的问题——类型转换
反射给对象赋值遇到的问题——类型转换 给一个对象属性赋值可以通过PropertyInfo.SetValue()方式进行赋值,但要注意值的类型要与属性保持一致. 创建对象实例的两种方法: 1. 1 ...
- python高级(2)—— 基础回顾2
回顾知识 一 操作系统的作用: 隐藏丑陋复杂的硬件接口,提供良好的抽象接口 管理.调度进程,并且将多个进程对硬件的竞争变得有序 关于操作系统的发展史,可以参考我之前的一篇博文:传送门 二 多道技术: ...
- iOS 验证码按钮倒计时
在app 注册或者登录 需要验证码的地方.为了避免短时间内刷验证码.往往会加上一层验证. 倒计时结束后.可以重新获取! 代码实现如下: // _CountdownTime 倒计时总时间: //_tim ...
- SMB协议原理抓包分析
SMB协议原理抓包分析 目录: 1.SMB概述 2.SMB原理 3.SMB配置 一.SMB概述 SMB(全称是Server Message Block)是一个协议名,可用于在计算机间共享文件.打印机. ...
- python模块:xlsxwriter和xlrd相结合读取、写入excel文件
python模块简单说明: xlsxwriter:负责写入数据 xlrd:负责读取数据 xlsxwriter 官方文档:http://xlsxwriter.readthedocs.org 本实例是刚写 ...