spring Aop 之用戶操作日誌以及異常處理日誌記錄

轉自~~http://m635674608.iteye.com/blog/1678995


使用Aop做操作日誌,異常處理,並記錄日誌。

方法1:try{}catch(){記錄日誌}

方法2:通過filter,或者strtus2攔截器(目前項目是struts2)

方法3:hirbernate的攔截器記錄日誌

方法4:通過jvm agent 代理

方法5:自定義類加載器應該也可以

雖然說各有個的好處吧,但是我個人還是喜歡Aop,當然Aop有多種實現。目前項目上用的是Spring Aop的 Aspect 。

我覺得使用Aop會更加的解耦合,更加的從其他的業務代碼中分離出來。和上一篇做方法緩存差不多,上代碼。

 

首先定義個註解,用於記錄該方法的描述

import java.lang.annotation.Documented;
import java.lang.annotation.ElementType;
import java.lang.annotation.Retention;
import java.lang.annotation.RetentionPolicy;
import java.lang.annotation.Target;

@Target({ElementType.METHOD,ElementType.TYPE})
@Retention(RetentionPolicy.RUNTIME)
@Documented
public @interface MethodLog {
	String remark() default "";
}

Action類


public class Sev {
	@MethodLog(remark="增加用戶信息")
	public String addUser(int type,int parentid){
		return "";
	}
}

Aop 類

package com.zhang.shine.cache;

import java.lang.reflect.Method;

import org.aspectj.lang.ProceedingJoinPoint;
import org.aspectj.lang.annotation.Around;
import org.aspectj.lang.annotation.Aspect;
import org.aspectj.lang.annotation.Pointcut;

@Aspect
public class MethodLogAspectJ {
//@Around("execution(* com.cms.controller.*.*.*(..)) && @annotation(sysLog)")  
	@Pointcut("@annotation(com.zhang.shine.cache.MethodLog)")
	public void methodCachePointcut() {
	}

	@Around("methodCachePointcut()")
	public Object methodCacheHold(ProceedingJoinPoint joinPoint)
			throws Throwable {
		System.out.println("aop start ");
		String methodRemark = getMthodRemark(joinPoint);
		Object result = null;
		try {
			// 記錄操作日誌...誰..在什麼時間..做了什麼事情..
			result = joinPoint.proceed();
		} catch (Exception e) {
			// 異常處理記錄日誌..log.error(e);
			throw e;
		}

		System.out.print(methodRemark);
		System.out.println("aop end ");
		return result;
	}

	// 獲取方法的中文備註____用於記錄用戶的操作日誌描述
	public static String getMthodRemark(ProceedingJoinPoint joinPoint)
			throws Exception {
		String targetName = joinPoint.getTarget().getClass().getName();
		String methodName = joinPoint.getSignature().getName();
		Object[] arguments = joinPoint.getArgs();

		Class targetClass = Class.forName(targetName);
		Method[] method = targetClass.getMethods();
		String methode = "";
		for (Method m : method) {
			if (m.getName().equals(methodName)) {
				Class[] tmpCs = m.getParameterTypes();
				if (tmpCs.length == arguments.length) {
					MethodLog methodCache = m.getAnnotation(MethodLog.class);
					methode = methodCache.remark();
					break;
				}
			}
		}
		return methode;
	}

}





   <aop:config>節點中proxy-target-class="true"不爲true時。

當登錄的時候會報這個異常java.lang.NoSuchMethodException: $Proxy54.login(),

是因爲代理Action類的時候,如果Proxy-targer-class=false,默認是用jdk動態代理。

所以代理不了Action類。




--------------------------------------更準確的獲得方法----------------------------------

@Target(ElementType.METHOD)
@Retention(RetentionPolicy.RUNTIME)
public @interface SysLog {
	String value();
}

 Signature signature = proJoinPoint.getSignature();
 MethodSignature methodSignature = (MethodSignature)signature;
 Method m = methodSignature.getMethod();
 System.out.println(m.getAnnotation(SysLog.class));
 SysLog a = m.getAnnotation(SysLog.class);
 if(a!=null){
 System.out.println(a.value());
 }



發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章