spring aop方法拦截器MVC中配aop拦截不生效,咋回事

SpringMVC中配置AOP拦截controller - 开源中国社区
当前访客身份:游客 [
当前位置:
小弟对spring aop不熟,现在有个项目需要记录日志,不想每个controller中去写,就想使用AOP,结果呢,配置后启动没错,但不出来
&?xml version=&1.0& encoding=&UTF-8&?&
&beans xmlns=&http://www.springframework.org/schema/beans&
xmlns:xsi=&http://www.w3.org/2001/XMLSchema-instance& xmlns:mvc=&http://www.springframework.org/schema/mvc&
xmlns:aop=&http://www.springframework.org/schema/aop& xmlns:context=&http://www.springframework.org/schema/context&
xsi:schemaLocation=&
http://www.springframework.org/schema/mvc http://www.springframework.org/schema/mvc/spring-mvc-3.0.xsd
http://www.springframework.org/schema/beans http://www.springframework.org/schema/beans/spring-beans-3.0.xsd
http://www.springframework.org/schema/context http://www.springframework.org/schema/context/spring-context-3.0.xsd
http://www.springframework.org/schema/aop http://www.springframework.org/schema/aop/spring-aop.xsd &&
&!-- DispatcherServlet Context: defines this servlet's request-processing
infrastructure --&
&!-- Scans within the base package of the application for @Components to
configure as beans --&
&!-- @Controller, @Service, @Configuration, etc. --&
&aop:aspectj-autoproxy proxy-target-class=&true& /&
&mvc:resources location=&/css/& mapping=&/css/**& /&
&mvc:resources location=&/img/& mapping=&/img/**& /&
&mvc:resources location=&/js/& mapping=&/js/**& /&
&mvc:resources location=&/json/& mapping=&/json/**& /&
&mvc:resources location=&/jquery-easyui-1.3.3/& mapping=&/jquery-easyui-1.3.3/**& /&
&bean id=&multipartResolver&
class=&org.springframework.monsMultipartResolver&&
&property name=&maxUploadSize& value=&& /&
&/beans& 然后呢,AOP类
package com.*.windrunner.
import org.aspectj.lang.JoinP
import org.aspectj.lang.annotation.A
import org.aspectj.lang.annotation.B
import org.aspectj.lang.annotation.P
import org.
@Component
public class ControllerLogAspect {
@Before(value = &execution(* com.*.windrunner.controller.*(..))&)
public void beforeMethod(JoinPoint point) {
System.out.println(&------test aop before&);
这个里面因为有公司项目,所以把包名用*号代替了,见谅!!现在不输,求帮忙
共有7个答案
<span class="a_vote_num" id="a_vote_num_
controller里面无法直接这样切入的。需要切入
execution(* org.springframework.web.servlet.mvc.annotation.AnnotationMethodHandlerAdapter.handle(..))
因为你controller注解的类,都被这个org.springframework.web.servlet.mvc.annotation.AnnotationMethodHandlerAdapter给代理了。
--- 共有 1 条评论 ---
谢谢,我想请问下,还有没有其它的配置需要做呢?谢谢
(3年前)&nbsp&
<span class="a_vote_num" id="a_vote_num_
我的功能和你类似,是这么写的
* 异常日志处理
* @param joinPoint
* @param throwable
// 拦截语法
// AbstractAction的子类被@RequestMapping注解的方法
@Around(&within(cn.org.sysu.cems.utils.superclass.AbstractAction+) && @annotation(org.springframework.web.bind.annotation.RequestMapping)&)
public ModelAndView handleError(ProceedingJoinPoint joinPoint) { 主要是那个@annotation 如果光用execution的话可能会把你Controller本身的getter setter等非请求处理方法一并给拦截了
--- 共有 1 条评论 ---
请问我这个配置对吗?我没有配appalicationContext.xml,上面的XML是spring-servlet.xml
(3年前)&nbsp&
<span class="a_vote_num" id="a_vote_num_
引用来自“汉唐”的答案 controller里面无法直接这样切入的。需要切入
execution(* org.springframework.web.servlet.mvc.annotation.AnnotationMethodHandlerAdapter.handle(..))
因为你controller注解的类,都被这个org.springframework.web.servlet.mvc.annotation.AnnotationMethodHandlerAdapter给代理了。 不需要了。现在还是无效?
--- 共有 4 条评论 ---
: 你看我的1楼回答,配置个AOP代理就可以了
(2年前)&nbsp&
: 你好,请问是怎么解决的呢?我也遇到这个问题了。 springmvc里面使用aop不起作用。。
(2年前)&nbsp&
。。。对不起,已经好了,我把两个项目搞混 了,配置的包错了,非常感谢!
(3年前)&nbsp&
还是无效,这评论不太会用,麻烦您看下下面我自己的评论
(3年前)&nbsp&
<span class="a_vote_num" id="a_vote_num_
引用来自“汉唐”的答案引用来自“汉唐”的答案 controller里面无法直接这样切入的。需要切入
execution(* org.springframework.web.servlet.mvc.annotation.AnnotationMethodHandlerAdapter.handle(..))
因为你controller注解的类,都被这个org.springframework.web.servlet.mvc.annotation.AnnotationMethodHandlerAdapter给代理了。 不需要了。现在还是无效?不用客气& ,好了就好。&
<span class="a_vote_num" id="a_vote_num_
最好不要这么处理日志,你想记录什么日志?访问日志吗?
--- 共有 2 条评论 ---
管理员的操作日志没有必要使用aop 使用过滤器和拦截器就可以了,具体参见的日志管理
(3年前)&nbsp&
管理员操作日志,不想在每个类里面写
(3年前)&nbsp&
<span class="a_vote_num" id="a_vote_num_
<span class="a_vote_num" id="a_vote_num_
&问题解决了。 目测大部分同学的aop失效都是因为在springmvc的配置文件里面扫描了类,那么spring去扫描的时候发现内存中已经有了对象,就不会在对类进行aop增强。所以当我们确定在那一层切入的时候,那么在springmvc的配置文件中,应该要排除欲切入的层。
&!-- 扫描的时候过滤掉Service层,aop要在service进行切入!
&context:component-scan base-package=&audit&&
&context:exclude-filter type=&annotation& expression=&org.springframework.stereotype.Service&/&
&/context:component-scan& 在spring里面扫描service 层
&context:component-scan base-package=&com.**.service& /&
OK.问题完美解决。 一个小问题纠结了好久。
更多开发者职位上
有什么技术问题吗?
tianpen...的其它问题
类似的话题SpringMVC中,捕杀Controller返回值进行拦截处理 - VC/MFC当前位置:& &&&SpringMVC中,捕杀Controller返回值进行拦截处理SpringMVC中,捕杀Controller返回值进行拦截处理&&网友分享于:&&浏览:0次SpringMVC中,捕捉Controller返回值进行拦截处理
SpringMVC中,首先是Interceptor,另外就是实现WebRequestInterceptor可以在请求Controller之前和执行之后进行拦截处理但是还没有发现如何获取调用方法的返回值所以,就打算自己通过AOP来写返回值的捕捉并进行相应的处理应用场景是,我希望通过MVC返回的结果是统一的格式和规则,并且有一些预设字段使用AOP时,会分别有CGLIB和Java自带的动态代理,但是对于Controller的捕捉,我看网上说无法使用自带的动态代理,所以,此处使用CGLIB
&dependency&
&groupId&cglib&/groupId&
&artifactId&cglib-nodep&/artifactId&
&version&${cglib.version}&/version&
&/dependency&
&dependency&
&groupId&org.aspectj&/groupId&
&artifactId&aspectjrt&/artifactId&
&version&${aspectj.version}&/version&
&/dependency&
&dependency&
&groupId&org.aspectj&/groupId&
&artifactId&aspectjweaver&/artifactId&
&version&${aspectj.version}&/version&
&/dependency&
pom里面所加我是使用了注解形式,需要在Spring配置文件中添加&aop:aspectj-autoproxy /&@Component首先注册切入点@Pointcut("execution(* com.liyunpeng.www.gateway.controller.*.*(..))")& &&& public void resultMapAspect(){}& 再根据切入点,配置相应的执行方法@AfterReturning(value = "resultMapAspect()",returning="resultMap")&&& public void abc(JoinPoint joinpoint,Object resultMap) throws Throwable {此处的resultMap就是通过Controller之后的返回值了,我们可以进行处理相关的内容另外,也可以通过aop:config标签来配置aop除了afterReturning意外,还有before around after,分别是执行前、执行前+后、执行后只不过afterReturning可以获取对应的返回值和参数。
12345678910
12345678910
12345678910 上一篇:下一篇:文章评论相关解决方案 1234567891011 Copyright & &&版权所有共有 2537 人关注过本帖
标题:spring mvc 中如何使用aop拦截到@controller?
来 自:四川成都
等 级:新手上路
帖 子:16
结帖率:20%
&&已结贴√
&&问题点数:15&&回复次数:2&&&
spring mvc 中如何使用aop拦截到@controller?
spring mvc 中@controller注解在初始化时被代理,请教一下如何使用aop拦截到@controller,有说实现HanlderInterceptorAdapter的,请具体指教一下,新人上路多多关照...
搜索更多相关主题的帖子:
等 级:版主
威 望:75
帖 子:645
专家分:4162
是要使用拦截器吗?
等 级:版主
威 望:75
帖 子:645
专家分:4162
&&得分:15&
程序代码://配置你的拦截器的bean
&!-- 日志拦截器 --&
&&&bean id=&loggerInterception& class=&web.interceptor.LoggerInterception& /&//class填写地址
&bean class=&org.springframework.web.servlet.mvc.annotation.DefaultAnnotationHandlerMapping&&
&&&&&&&&&property name=&interceptors&&
&&&&&&&&&&&&&list&
&&&&&&&&&&&&&&& &ref bean=&loggerInterception&/&
&&&&&&&&&&&&&/list&
&&&&&&&&&/property&
&&& &/bean&
//------------------------分割线-----------------------
public class LoggerInterception extends HandlerInterceptorAdapter{
&&& private static Log log = Log.getLog(LoggerInterception.class);
&&& @Override
&&& public void afterCompletion(HttpServletRequest request,
&&&&&&&&&&&&HttpServletResponse response, Object handler, Exception ex)
&&&&&&&&&&&&throws Exception {
&&&&&&&&// TODO Auto-generated method stub
&&&&&&&&super.afterCompletion(request, response, handler, ex);
&&& @Override
&&& public void postHandle(HttpServletRequest request,
&&&&&&&&&&&&HttpServletResponse response, Object handler,
&&&&&&&&&&&&ModelAndView modelAndView) throws Exception {
&&&&&&&&(&modelAndView:&+modelAndView);
&&&&&&&&super.postHandle(request, response, handler, modelAndView);
&&& @Override
&&& public boolean preHandle(HttpServletRequest request,
&&&&&&&&&&&&HttpServletResponse response, Object handler) throws Exception {
&&&&&&&&(&request:&+request.getRequestURI());
&&&&&&&&return super.preHandle(request, response, handler);
版权所有,并保留所有权利。
Powered by , Processed in 0.036241 second(s), 8 queries.
Copyright&, BCCN.NET, All Rights Reserved使用AOP与注解记录Java日志 - ImportNew
| 标签: , , ,
有些时候,我想要把每个运行过的方法接收到的参数、返回值和执行时间等信息记录(通过slf4j 和 log4j)下来。在AspectJ、jcabi-aspects和Java注解的帮助下我实现了这个想法。
public class Foo {
public int power(int x, int p) {
return Math.pow(x, p);
在log4j中可以看到以下输出:
[INFO] com.example.Foo #power(2, 10): 1024 in 12μs
[INFO] com.example.Foo #power(3, 3): 27 in 4μs
看上去很酷对吧?接下来我们来看看它是如何工作的。
注解是Java 6中采用的一种技术(译注:其实Java 5就有注解了)。它是一种不会影响程序运行的元编程指令,我们可以用它来对一些指定的元素(方法、类或者变量)进行标记。换句话说,注解就是代码中可以看到的标记。一些注解只在编译阶段可见——它们不存在于编译好的.class文件中,另外一些注解在编译后仍然可见。
例如,是第一种类型(它的保留类型是),而JUnit的是第二种类型(保留类型是),——我在上面使用过的是第二种注解,包含在jcabi-aspects中,在编译后会留在.class文件中。
值得注意的是,上文的power()方法即便被注解并且编译,也不会发送任何内容到slf4j。仅仅是一种用来提醒相关软件“请记录我的执行过程”的标记, 理解这一点很重要。
(面向切面编程)是一种可以在对源代码不作明显改动的情况下向其加入可执行块的技术。在上面的示例中,我们不想在实现类中记录方法的执行,而是用其他类去拦截power()方法的每次调用,测量执行时间并把这些信息发送给slf4j。
我想要使拦截类能识别@Loggable注解并且记录下power()方法的每次调用,当然它也应该能拦截其他方法。
这个想法与AOP的出发点很符合——避免在多个类中重复实现一些共同的功能。
日志是Java主要功能的一个补充。我们不想往代码中加入繁杂的日志指令,这样会导致代码可读性降低,所以我们想在别的地方偷偷地记录日志。
从AOP的角度来看,我们的解决方案是新建一个指定切入点和环绕通知的切面以实现预期的功能。
接下来,让我们来看看这些神奇的注解。首先,让我们来了解是如何用来实现注解的。下面是一个简单例子,你可以在中找到全部代码。
public class MethodLogger {
@Around(&execution(* *(..)) && @annotation(Loggable)&)
public Object around(ProceedingJoinPoint point) {
long start = System.currentTimeMillis();
Object result = point.proceed();
&#%s(%s): %s in %[msec]s&,
MethodSignature.class.cast(point.getSignature()).getMethod().getName(),
point.getArgs(),
System.currentTimeMillis() - start
这个切面(aspect)里有一个around()通知,切面用@Aspect注解,通知用@Around注解, 上面提到过这些注解仅仅是在.class文件中做了标记,这些标记在运行时能提供一些信息给那些对它们感兴趣对象。
@Around注解有一个参数,如果该方法
可见性是 * (public、protected或private);
名字是 * (任何名字都可以);
参数是 .. (任何参数都可以);
注解为@Loggable
那么通知就会应用到该方法。
当注解方法被调用的时就会被拦截,around()通知会在被拦截方法之前执行,其中 @Around 类型的通知需要一个 ProceedingJoinPoint 类的实例作为参数,之后返回一个对象给power()方法。
为了调用power()方法,通知需要调用join point对象的proceed()方法。
接下来编译并把它加入环境变量,让我们的主文件Foo.class能够调用它。目前为止一切顺利,我们还需要最后一步——把通知运转起来。
二进制切面织入
切面织入(aspect waving)就是将切面应用到目标对象从而创建一个新的代理对象的过程。切面织入将一些代码插入原代码,AspectJ就是这么做的。我们给它两个二进制Java类Foo.class 和 MethodLogger.class; 它返回三个类——修改过的Foo.class、Foo$AjcClosure1.class和未修改的MethodLogger.class。
为了理解如何将不同的通知应用于对应的哪个方法,AspectJ织入在.class文件中使用了注解,并使用来浏览环境变量中的所有类。它分析@Around注解中的哪个方法满足条件。power()就在此时被发现了。
上述操作需要分为两步。首先,我们把.java文件编译。然后AspectJ对编译后的文件进行织入/修改,织入后的Foo类看起来像下面这样:
public class Foo {
private final MethodL
public int power(int x, int p) {
return this.logger.around(point);
private int power_aroundBody(int x, int p) {
return Math.pow(x, p);
AspectJ织入把我们原来的功能移到新方法power_aroundBody()中,并把所有的power()调用重定向到切面类MethodLogger。
下图是每次调用power()的过程:
图中那一小块绿色就是原方法power()。
如你所见,切面织入过程把类和切面等联系起来了。如果没有织入,它们仅仅是一堆编译好的二进制代码和注解。
jcabi-aspects
是一个含有Loggable注解和MethodLogger切面的JAR库,它还有其它注解和切面。你不必自己实现切面,只要在环境变量加入一些依赖并为切面织入配置好。可以到获取最新版本。
&depenencies&
&dependency&
&dependency&
&groupId&com.jcabi&/groupId&
&artifactId&jcabi-aspects&/artifactId&
&/dependency&
&dependency&
&groupId&org.aspectj&/groupId&
&artifactId&aspectjrt&/artifactId&
&/dependency&
&/dependency&
&/depenencies&
&groupId&com.jcabi&/groupId&
&artifactId&jcabi-maven-plugin&/artifactId&
&executions&
&execution&
&goal&ajc&/goal&
&/execution&
&/executions&
&/plugins&
&/project&
由于织入过程比较复杂,我用Maven插件和ajc goal做了一个便捷的织入。你也可以直接用AspectJ,不过我还是推荐你使用。
好了,现在你可以用 注解你的方法执行过程将会通过slf4j记录下来。
如果按上述操作没有得到预期效果,欢迎到提出问题。
原文链接:
- 译文链接: [ 转载请保留原文出处、译者和译文链接。]
关于作者:
(新浪微博:)
关于ImportNew
ImportNew 专注于 Java 技术分享。于日 11:11正式上线。是的,这是一个很特别的时刻 :)
ImportNew 由两个 Java 关键字 import 和 new 组成,意指:Java 开发者学习新知识的网站。 import 可认为是学习和吸收, new 则可认为是新知识、新技术圈子和新朋友……
新浪微博:
推荐微信号
反馈建议:@
广告与商务合作QQ:
&#8211; 好的话题、有启发的回复、值得信赖的圈子
&#8211; 写了文章?看干货?去头条!
&#8211; 为IT单身男女服务的征婚传播平台
&#8211; 优秀的工具资源导航
&#8211; 活跃 &#038; 专业的翻译小组
&#8211; 国内外的精选博客文章
&#8211; UI,网页,交互和用户体验
&#8211; JavaScript, HTML5, CSS
&#8211; 专注Android技术分享
&#8211; 专注iOS技术分享
&#8211; 专注Java技术分享
&#8211; 专注Python技术分享
& 2016 ImportNew}

我要回帖

更多关于 spring aop 拦截两次 的文章

更多推荐

版权声明:文章内容来源于网络,版权归原作者所有,如有侵权请点击这里与我们联系,我们将及时删除。

点击添加站长微信