spring aop記錄日誌,Log4j

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

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

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

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

方法4:通過jvm agent 代理

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

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

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

 

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

Java代碼  收藏代碼
  1. import java.lang.annotation.Documented;  
  2. import java.lang.annotation.ElementType;  
  3. import java.lang.annotation.Retention;  
  4. import java.lang.annotation.RetentionPolicy;  
  5. import java.lang.annotation.Target;  
  6.   
  7. @Target({ElementType.METHOD,ElementType.TYPE})  
  8. @Retention(RetentionPolicy.RUNTIME)  
  9. @Documented  
  10. public @interface MethodLog {  
  11.     String remark() default "";  
  12. }  

 

   Action類

    

Java代碼  收藏代碼
  1. public class Sev {  
  2.     @MethodLog(remark="增加用戶信息")  
  3.     public String addUser(int type,int parentid){  
  4.         return "";  
  5.     }  
  6. }  

 

  Aop 類

   

 

Java代碼  收藏代碼
  1. package com.zhang.shine.cache;  
  2.   
  3. import java.lang.reflect.Method;  
  4.   
  5. import org.aspectj.lang.ProceedingJoinPoint;  
  6. import org.aspectj.lang.annotation.Around;  
  7. import org.aspectj.lang.annotation.Aspect;  
  8. import org.aspectj.lang.annotation.Pointcut;  
  9.   
  10. @Aspect  
  11. public class MethodLogAspectJ {  
  12.   
  13.     @Pointcut("@annotation(com.zhang.shine.cache.MethodLog)")  
  14.     public void methodCachePointcut() {  
  15.     }  
  16.   
  17.     @Around("methodCachePointcut()")  
  18.     public Object methodCacheHold(ProceedingJoinPoint joinPoint)  
  19.             throws Throwable {  
  20.         System.out.println("aop start ");  
  21.         String methodRemark = getMthodRemark(joinPoint);  
  22.         Object result = null;  
  23.         try {  
  24.             // 記錄操作日誌...誰..在什麼時間..做了什麼事情..  
  25.             result = joinPoint.proceed();  
  26.         } catch (Exception e) {  
  27.             // 異常處理記錄日誌..log.error(e);  
  28.             throw e;  
  29.         }  
  30.   
  31.         System.out.print(methodRemark);  
  32.         System.out.println("aop end ");  
  33.         return result;  
  34.     }  
  35.   
  36.     // 獲取方法的中文備註____用於記錄用戶的操作日誌描述  
  37.     public static String getMthodRemark(ProceedingJoinPoint joinPoint)  
  38.             throws Exception {  
  39.         String targetName = joinPoint.getTarget().getClass().getName();  
  40.         String methodName = joinPoint.getSignature().getName();  
  41.         Object[] arguments = joinPoint.getArgs();  
  42.   
  43.         Class targetClass = Class.forName(targetName);  
  44.         Method[] method = targetClass.getMethods();  
  45.         String methode = "";  
  46.         for (Method m : method) {  
  47.             if (m.getName().equals(methodName)) {  
  48.                 Class[] tmpCs = m.getParameterTypes();  
  49.                 if (tmpCs.length == arguments.length) {  
  50.                     MethodLog methodCache = m.getAnnotation(MethodLog.class);  
  51.                     methode = methodCache.remark();  
  52.                     break;  
  53.                 }  
  54.             }  
  55.         }  
  56.         return methode;  
  57.     }  
  58.   
  59. }  

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

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

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

所以代理不了Action類。

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