想使用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的自动扫描配置

  1. 代码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中的方法的更多相关文章

  1. Spring的Aspect切面类不能拦截Controller中的方法

    根本原因在于<aop:aspectj-autoproxy />这句话是在spring的配置文件内,还是在springmvc的配置文件内.如果是在spring的配置文件内,则@Control ...

  2. spingAOP在springMVC中的使用(我用在拦截controller中的方法。主要用于登录控制)

    首先截取了网上的一张配置execution的图片 我在项目中关于aop的配置:如果拦截controller的方法,需要在spring-mvc.xml文件中加入(如果在spring.xml中加入则无法拦 ...

  3. spring aop无法拦截类内部的方法调用

    1.概念 拦截器的实现原理就是动态代理,实现AOP机制.Spring 的代理实现有两种:一是基于 JDK Dynamic Proxy 技术而实现的:二是基于 CGLIB 技术而实现的.如果目标对象实现 ...

  4. Spring AOP无法拦截Controller的原因

    因为Spring的Bean扫描和Spring-MVC的Bean扫描是分开的, 两者的Bean位于两个不同的Application, 而且Spring-MVC的Bean扫描要早于Spring的Bean扫 ...

  5. Spring AOP无法拦截Controller

    参考@参考文章中的评论 首先,应该打开aop代理 <aop:aspectj-autoproxy proxy-target-class="true"/> 其次,应该讲ao ...

  6. Spring AOP获取拦截方法的参数名称跟参数值

    注意:这种方式需要JDK1.8版本支持 开始:http://www.cnblogs.com/wing7319/p/9592184.html 1.aop配置: <aop:aspectj-autop ...

  7. Spring AOP开发时如何得到某个方法内调用的方法的代理对象?

    Spring AOP开发时如何得到某个方法内调用的方法的代理对象? 问题阅读起来拗口,看代码 在方法中调用其他方法很常见,也经常使用,如果在一个方法内部调用其他方法,比如 public class U ...

  8. ASP.NET MVC4在View中调用当前Controller中的方法

    调用当前Controller中的方法 @{ ((HomeController)ViewContext.Controller).Method1(); } 调用静态方法 @{ SomeClass.Meth ...

  9. Spring AOP不拦截从对象内部调用的方法原因

    拦截器的实现原理很简单,就是动态代理,实现AOP机制.当外部调用被拦截bean的拦截方法时,可以选择在拦截之前或者之后等条件执行拦截方法之外的逻辑,比如特殊权限验证,参数修正等操作. 但是最近在项目中 ...

随机推荐

  1. 解决ui-router路由监听$stateChangeStart、$stateChangeSuccess、$stateChangeError不执行的问题

    问题解答 angular1项目导入ui-router之后,使用路由监听,代码如下 angular.module('app', ['ui.router', 'ui.router.state.events ...

  2. Boostrap模态框,以及通过jquery绑定td的值,使模态框回显

    做页面不管是登录或是修改信息,难免会使用到模态框,在此分享一个比较漂亮的模态框 Boostrap模态框 使用之前首先导入jquery-3.2.1.min.js,和bootstrap.min.js 先添 ...

  3. Flutter 布局(五)- LimitedBox、Offstage、OverflowBox、SizedBox详解

    本文主要介绍Flutter布局中的LimitedBox.Offstage.OverflowBox.SizedBox四种控件,详细介绍了其布局行为以及使用场景,并对源码进行了分析. 1. Limited ...

  4. Percona XtraBackup 备份还原篇

    Percona XtraBackup 安装介绍篇已经对Percona XtraBackup的功能和安装做了比较详细的介绍,那么本篇我们直接进入主题,如何使用XtraBackup做备份.还原,下面主要介 ...

  5. request获取各种路径

    equest.getRealPath() 这个方法已经不推荐使用了,代替方法是: request.getSession().getServletContext().getRealPath() 在ser ...

  6. org.hibernate.NonUniqueObjectException

    错误如下: 2017-3-29 15:17:52~ERROR~org.apache.catalina.core.StandardWrapperValve.invoke(StandardWrapperV ...

  7. 转:Redis 使用经验总结

    转自:Redis 总结精讲 看一篇成高手系统-4 本文围绕以下几点进行阐述 1.为什么使用redis2.使用redis有什么缺点3.单线程的redis为什么这么快4.redis的数据类型,以及每种数据 ...

  8. Cisco 日常巡检命令

    https://www.cnblogs.com/qzqdy/p/8116903.html 日常排错命令6 交换机的前面板有几个指示灯,用于监控系统的活动和性能.这些指示灯称之为发二极管(LED) 1. ...

  9. Ajax入门例子

    在customer.php的文件中,代码如下: <html> <head> <script type="text/javascript"> fu ...

  10. 枚举应用demo

    package com.xx; public enum PositionEM{ ONE(1,"领导"), TWO(2,"员工"); private Long v ...