除springMvc外须要引入@Aspect注解依赖:java
<!-- AOP --> <!-- https://mvnrepository.com/artifact/aopalliance/aopalliance --> <dependency> <groupId>org.aspectj</groupId> <artifactId>aspectjrt</artifactId> <version>1.6.11</version> </dependency> <dependency> <groupId>org.aspectj</groupId> <artifactId>aspectjweaver</artifactId> <version>1.6.11</version> </dependency> <dependency> <groupId>cglib</groupId> <artifactId>cglib</artifactId> <version>2.1_3</version> </dependency>
自定义注解标签:web
@Target({ ElementType.METHOD }) @Retention(RetentionPolicy.RUNTIME) @Documented @Inherited public @interface logAnnotation { /** * @param 模块名字 */ String modelName() default ""; /** * @param 操做类型 */ String option(); }
定义切面类:spring
@Aspect // 该注解标示该类为切面类 @Component // 注入依赖 public class OperationLogAspect { // 标注该方法体为后置通知,当目标方法执行成功后执行该方法体 @AfterReturning("within(com.ustcinfo.fccos.terminal.web..*) && @annotation(rl)") public void addLogSuccess(JoinPoint jp, logAnnotation rl) { System.out.println("&&&&&&&&&&&&&&&&&&&&&&&&&"); Object[] parames = jp.getArgs();// 获取目标方法体参数 String className = jp.getTarget().getClass().toString();// 获取目标类名 className = className.substring(className.indexOf("com")); String signature = jp.getSignature().toString();// 获取目标方法签名 String methodName = signature.substring(signature.lastIndexOf(".") + 1, signature.indexOf("(")); System.out.println("&&&&&&&&&&&&&&&&&&&&&&&&&"); } }
切面类可根据业务要求自行添加逻辑express
在spring的容器xml中添加配置:mybatis
<aop:aspectj-autoproxy/>
此处有个注意点:网上说利用AOP没法拦截controller层,经测试,须要在web mvc中同时添加注解mvc
<aop:aspectj-autoproxy/>
由于为了启用事务,在spring的容器扫描中排除了controller层:app
<context:annotation-config /> <!-- 对应的是系统级别的配置,做用范围是系统上下文 --> <context:component-scan base-package="com.ustcinfo.fccos.terminal.web"> <context:exclude-filter type="annotation" expression="org.springframework.stereotype.Controller" /> </context:component-scan>
在Mvc、中只启用了controller层的扫描:ide
<mvc:annotation-driven /> <!-- 对应的是 controller 级别的配置,做用范围是控制层上下文。初始话转发内容 --> <context:component-scan base-package="com.ustcinfo.fccos.terminal.web.controller"> <context:include-filter type="annotation" expression="org.springframework.stereotype.Controller" /> </context:component-scan>
所以,只须要在 spring的父容器,mvc子容器中均添加测试
<aop:aspectj-autoproxy/>
便可实现controller的拦截;spa
网上还有另一种说法,就是配置文件改为
<aop:aspectj-autoproxy proxy-target-class="true"/>让spring使用cglib的代理方式
可是cglib的时候须要有默认的构造方法,class不能为final的,所以在项目中引入了mybatis或者其余的无默认构造的方法时候就会报错:
java.lang.IllegalArgumentException: Cannot subclass final class class com.sun.proxy.$Proxy33
,经测试,只须要在 spring的父容器,mvc子容器中均添加
<aop:aspectj-autoproxy/>
便可实现controller以及其余业务的切面,网上说spring会自动在JDK动态代理和CGLIB之间转换,可是没作验证
查看aop是否生效
切面注解controller
@RequestMapping(value = "getInstallerInfos") @ResponseBody @logAnnotation(option = "查询装维_controller") public Json getInstallerInfos(String installer) {
@Override @logAnnotation(option = "查询装维_service") public Json getInstallerInfos(String installer) {
切面注解service
日志均打印代表测试成功