在controller中使用AOP的问题主要在于如何让controller可以被检测到。
controller和其余spring bean的区别在于:controller是由mvc定义并在web.xml中的dispatcher中定义的。
解决方法:
一、正肯定义controller,(比较通用的作法,没有特殊状况的话,大部分应用没有这个问题)
a. 将服务层的类都放在ApplicationCotext-*.xml中定义,在context listener中初始化(注意,任何controller都不该该在这里出现),要包括<aop:aspectj-autoproxy/>, 在这里,有没有proxy-target-class="true" 没有关系(具体含义参看下文)
b. 定义mvc的配置文件,通常是 <<servlet name>>-servlet.xml,通常(也是推荐作法)使用auto scan来定义全部的controller.关键步骤来了:这个文件也要加入<aop:aspectj-autoproxy proxy-target-class="true"/>, 必定要添加proxy-target-class="true"! 这是用于通知spring使用cglib而不是jdk的来生成代理方法。
c. 另一个事项,controller须要使用@controller注释,而不是继承abstract controller。
d. 建议使用aspectj来完成aop java
package com.kbs.platform.aop; import java.util.Arrays; import org.aspectj.lang.JoinPoint; import org.aspectj.lang.annotation.AfterReturning; import org.aspectj.lang.annotation.Aspect; @Aspect public class RemoteApiLogRecorder { //pointcut="execution(* com.abc.service.*.many*(..))", returning="returnValue" @AfterReturning(pointcut="execution(* com.kbs.platform.controller.AppLoginController.*(..))",returning="returnValue") public void afterHandle(JoinPoint point,Object returnValue){ System.out.println("@AfterReturning:模拟日志记录功能..."); System.out.println("@AfterReturning:目标方法为:" + point.getSignature().getDeclaringTypeName() + "." + point.getSignature().getName()); System.out.println("@AfterReturning:参数为:" + Arrays.toString(point.getArgs())); System.out.println("@AfterReturning:返回值为:" + returnValue); System.out.println("@AfterReturning:被织入的目标对象为:" + point.getTarget()); } }