java利用AOP 實現操做日誌記錄(一)

 除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

日誌均打印代表測試成功

相關文章
相關標籤/搜索