转载自:http://www.oschina.net/question/222929_124314
一般操作方式,但是这个对controller层无效:
package com.*.windrunner.aop;
import org.aspectj.lang.JoinPoint; import org.aspectj.lang.annotation.Aspect; import org.aspectj.lang.annotation.Before; import org.aspectj.lang.annotation.Pointcut; import org.springframework.stereotype.Component;
@Aspect @Component public class ControllerLogAspect {
@Before(value = "execution(* com.*.windrunner.controller.*(..))")
public void beforeMethod(JoinPoint point) {
System.out.println("------test aop before");
}
}
解决方案:
1、controller里面无法直接这样切入的。
需要切入 execution(* org.springframework.web.servlet.mvc.annotation.AnnotationMethodHandlerAdapter.handle(..))
因为你controller注解的类,都被这个org.springframework.web.servlet.mvc.annotation.AnnotationMethodHandlerAdapter给代理了。
2、
/**
* 异常日志处理
*
* @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等非请求处理方法一并给拦截了。
3、
目测大部分同学的aop失效都是因为在springmvc的配置文件里面扫描了类,那么spring去扫描的时候发现内存中已经有了对象,就不会在对类进行aop增强。所以当我们确定在那一层切入的时候,那么在springmvc的配置文件中,应该要排除欲切入的层。
<!-- 扫描的时候过滤掉Service层,aop要在service进行切入! -->
<context:component-scan base-package="com.xxx.infoaudit">
<context:exclude-filter type="annotation" expression="org.springframework.stereotype.Service"/>
</context:component-scan>
在spring里面扫描service 层
<context:component-scan base-package="com.**.service" />
关于第3点,直接切入service,貌似没什么问题。
<aop:aspectj-autoproxy />
<bean class="com.xx.aop.LogAspect" />
<context:component-scan base-package="com.xx.dao"/>
<context:component-scan base-package="com.xx.service"/>
关于切入点所在的类,这些类必须使用Spring context初始化,否则AOP将不会被执行。
更多阅读:spring aop 如何切面到mvc 的controller
Indeed your controller (annotated by @Controller) and your aspects (annotated by @Aspect) should be in the same Spring context.
Usually people define their controllers in the dispatch-servlet.xml or xxx-servlet.xml and their service beans (including the aspects) in the main applicationContext.xml. It will not work.
When Spring initializes the MVC context, it will create a proxy for your controller but if your aspects are not in the same context, Spring will not create interceptors for them.