about 8 years ago
有的時候會有特別需求要紀錄資料進入、出去以及是否執行成功,原則上是直接寫log就好,或是你需要一個統一而且不需要動到原本程式的話,使用AOP機制會是一個好方法。
先在設定檔檔頭部份加上AOP定義
<beans xmlns="http://www.springframework.org/schema/beans"
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xmlns:tx="http://www.springframework.org/schema/tx"
xmlns:aop="http://www.springframework.org/schema/aop"
xsi:schemaLocation="
http://www.springframework.org/schema/beans
http://www.springframework.org/schema/beans/spring-beans-3.0.xsd
http://www.springframework.org/schema/tx
http://www.springframework.org/schema/tx/spring-tx-3.0.xsd
http://www.springframework.org/schema/aop
http://www.springframework.org/schema/aop/spring-aop-3.0.xsd">
<!-- 啟用自動代理 -->
<aop:aspectj-autoproxy />
<!-- 定義代理的類別 -->
<bean id="logAspect" class="com.secom.mobile.system.LogAspect" />
</beans>
再新增一個類別
package com.secom.mobile.system;
import org.aspectj.lang.*;
import org.aspectj.lang.annotation.*;
@Aspect
public class LogAspect {
@Before("execution(* com.secom.mobile.modules.service..*(..))")
public void logBefore(JoinPoint joinPoint) {
System.out.println("logBefore() is running!");
//下面方法會抓到代理器名稱
//System.out.println("hijacked : " + joinPoint.getTarget().getClass().getName());
System.out.println("hijacked : " + joinPoint.getSignature().getName());
Object[] args = joinPoint.getArgs();
for(int i = 0 ;i < args.length ; i++){
System.out.println("params["+i+"]:"+ args[i].toString());
}
System.out.println("******");
}
@After("execution(* com.secom.mobile.modules.service..*(..))")
public void logAfter(JoinPoint joinPoint) {
System.out.println("logAfter() is running!");
System.out.println("hijacked : " + joinPoint.getSignature().getName());
System.out.println("******");
}
@AfterReturning(
pointcut = "execution(* com.secom.mobile.modules.service..*(..))",
returning= "result")
public void logAfterReturning(JoinPoint joinPoint, Object result) {
System.out.println("logAfterReturning() is running!");
System.out.println("hijacked : " + joinPoint.getSignature().getName());
System.out.println("Method returned value is : " + result);
System.out.println("******");
}
@AfterThrowing(
pointcut = "execution(* com.secom.mobile.modules.service..*(..))",
throwing= "error")
public void logAfterThrowing(JoinPoint joinPoint, Throwable error) {
System.out.println("logAfterThrowing() is running!");
System.out.println("hijacked : " + joinPoint.getSignature().getName());
System.out.println("Exception : " + error);
System.out.println("******");
}
// @Around("execution(* com.secom.mobile.modules.service..*(..))")
// public void logAround(ProceedingJoinPoint joinPoint) throws Throwable {
// System.out.println("logAround() is running!");
// System.out.println("hijacked method : " + joinPoint.getSignature().getName());
// System.out.println("hijacked arguments : " + Arrays.toString(joinPoint.getArgs()));
// System.out.println("Around before is running!");
// joinPoint.proceed(); //continue on the intercepted method
// System.out.println("Around after is running!");
// System.out.println("******");
// }
}
再來你可以取得這樣的資料
logBefore() is running!
hijacked : saveToken
params[0]:1
params[1]:202.39.240.74
params[2]:00A000002
params[3]:mitake
params[4]:202.39.240.74
logAfter() is running!
hijacked : saveToken
logAfterReturning() is running!
hijacked : saveToken
Method returned value is : com.secom.mobile.modules.entity.Tokenmana@23e31e9e
就可以來實現自己的紀錄或操作了
Reference
Spring AOP + AspectJ Annotation Example
Spring AOP对日志记录、Exception日志记录
良葛格spring學習筆記