使用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 {
- @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類。