除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
日誌均打印代表測試成功