亚洲香蕉成人av网站在线观看_欧美精品成人91久久久久久久_久久久久久久久久久亚洲_热久久视久久精品18亚洲精品_国产精自产拍久久久久久_亚洲色图国产精品_91精品国产网站_中文字幕欧美日韩精品_国产精品久久久久久亚洲调教_国产精品久久一区_性夜试看影院91社区_97在线观看视频国产_68精品久久久久久欧美_欧美精品在线观看_国产精品一区二区久久精品_欧美老女人bb

首頁 > 學院 > 開發設計 > 正文

SpringAOP攔截Controller,Service實現日志管理(自定義注解的方式)

2019-11-14 15:19:02
字體:
來源:轉載
供稿:網友

首先我們為什么需要做日志管理,在現實的上線中我們經常會遇到系統出現異常或者問題。這個時候就馬上打開CRT或者SSH連上服務器拿日子來分析。受網絡的各種限制。于是我們就想為什么不能直接在管理后臺查看報錯的信息呢。于是日志管理就出現了。

         其次個人覺得做日志管理最好的是Aop,有的人也喜歡用攔截器。都可以,在此我重點介紹我的實現方式。

         Aop有的人說攔截不到Controller。有的人說想攔AnnotationMethodHandlerAdapter截到Controller必 須得攔截 org.sPRingframework.web.servlet.mvc.annotation.AnnotationMethodHandlerAdapter。

首先Aop可以攔截到Controller的,這個是毋容置疑的其次須攔截AnnotationMethodHandlerAdapter也不是必須的。最起碼我沒有驗證成功過這個。我的Spring版本是4.0.3。

         Aop之所以有的人說攔截不到Controller是因為Controller被jdk代理了。我們只要把它交給cglib代理就可以了。

第一步定義兩個注解:


[java] view plaincopy
  1. package com.annotation;    
  2.     
  3. import java.lang.annotation.*;    
  4.     
  5. /**  
  6.  *自定義注解 攔截Controller  
  7.  */    
  8.     
  9. @Target({ElementType.PARAMETER, ElementType.METHOD})    
  10. @Retention(RetentionPolicy.RUNTIME)    
  11. @Documented    
  12. public  @interface SystemControllerLog {    
  13.     
  14.     String description()  default "";    
  15.     
  16.     
  17. }    
  18.     
  19. package com.annotation;    
  20.     
  21. import java.lang.annotation.*;    
  22.     
  23. /**  
  24.  *自定義注解 攔截service  
  25.  */    
  26.     
  27. @Target({ElementType.PARAMETER, ElementType.METHOD})    
  28. @Retention(RetentionPolicy.RUNTIME)    
  29. @Documented    
  30. public  @interface SystemServiceLog {    
  31.     
  32.     String description()  default "";    
  33.     
  34.     
  35. }    




第二步創建一個切點類:


[java] view plaincopy
  1. package com.annotation;    
  2.     
  3. import com.model.Log;    
  4. import com.model.User;    
  5. import com.service.LogService;    
  6. import com.util.DateUtil;    
  7. import com.util.JSONUtil;    
  8. import com.util.SpringContextHolder;    
  9. import com.util.WebConstants;    
  10. import org.aspectj.lang.JoinPoint;    
  11. import org.aspectj.lang.annotation.*;    
  12. import org.slf4j.Logger;    
  13. import org.slf4j.LoggerFactory;    
  14. import org.springframework.stereotype.Component;    
  15. import org.springframework.web.context.request.RequestContextHolder;    
  16. import org.springframework.web.context.request.ServletRequestAttributes;    
  17. import javax.annotation.Resource;    
  18. import javax.servlet.http.HttpServletRequest;    
  19. import javax.servlet.http.Httpsession;    
  20. import java.lang.reflect.Method;    
  21.     
  22. /**  
  23.  * 切點類  
  24.  * @author tiangai  
  25.  * @since 2014-08-05 Pm 20:35  
  26.  * @version 1.0  
  27.  */    
  28. @Aspect    
  29. @Component    
  30. public  class SystemLogAspect {    
  31.     //注入Service用于把日志保存數據庫    
  32.     @Resource    
  33.      private LogService logService;    
  34.     //本地異常日志記錄對象    
  35.      private  static  final Logger logger = LoggerFactory.getLogger(SystemLogAspect. class);    
  36.     
  37.     //Service層切點    
  38.     @Pointcut("@annotation(com.annotation.SystemServiceLog)")    
  39.      public  void serviceAspect() {    
  40.     }    
  41.     
  42.     //Controller層切點    
  43.     @Pointcut("@annotation(com.annotation.SystemControllerLog)")    
  44.      public  void controllerAspect() {    
  45.     }    
  46.     
  47.     /**  
  48.      * 前置通知 用于攔截Controller層記錄用戶的操作  
  49.      *  
  50.      * @param joinPoint 切點  
  51.      */    
  52.     @Before("controllerAspect()")    
  53.      public  void doBefore(JoinPoint joinPoint) {    
  54.     
  55.         HttpServletRequest request = ((ServletRequestAttributes) RequestContextHolder.getRequestAttributes()).getRequest();    
  56.         HttpSession session = request.getSession();    
  57.         //讀取session中的用戶    
  58.         User user = (User) session.getAttribute(WebConstants.CURRENT_USER);    
  59.         //請求的IP    
  60.         String ip = request.getRemoteAddr();    
  61.          try {    
  62.             //*========控制臺輸出=========*//    
  63.             System.out.println("=====前置通知開始=====");    
  64.             System.out.println("請求方法:" + (joinPoint.getTarget().getClass().getName() + "." + joinPoint.getSignature().getName() + "()"));    
  65.             System.out.println("方法描述:" + getControllerMethodDescription(joinPoint));    
  66.             System.out.println("請求人:" + user.getName());    
  67.             System.out.println("請求IP:" + ip);    
  68.             //*========數據庫日志=========*//    
  69.             Log log = SpringContextHolder.getBean("logxx");    
  70.             log.setDescription(getControllerMethodDescription(joinPoint));    
  71.             log.setMethod((joinPoint.getTarget().getClass().getName() + "." + joinPoint.getSignature().getName() + "()"));    
  72.             log.setType("0");    
  73.             log.setRequestIp(ip);    
  74.             log.setExceptionCode( null);    
  75.             log.setExceptionDetail( null);    
  76.             log.setParams( null);    
  77.             log.setCreateBy(user);    
  78.             log.setCreateDate(DateUtil.getCurrentDate());    
  79.             //保存數據庫    
  80.             logService.add(log);    
  81.             System.out.println("=====前置通知結束=====");    
  82.         }  catch (Exception e) {    
  83.             //記錄本地異常日志    
  84.             logger.error("==前置通知異常==");    
  85.             logger.error("異常信息:{}", e.getMessage());    
  86.         }    
  87.     }    
  88.     
  89.     /**  
  90.      * 異常通知 用于攔截service層記錄異常日志  
  91.      *  
  92.      * @param joinPoint  
  93.      * @param e  
  94.      */    
  95.     @AfterThrowing(pointcut = "serviceAspect()", throwing = "e")    
  96.      public  void doAfterThrowing(JoinPoint joinPoint, Throwable e) {    
  97.         HttpServletRequest request = ((ServletRequestAttributes) RequestContextHolder.getRequestAttributes()).getRequest();    
  98.         HttpSession session = request.getSession();    
  99.         //讀取session中的用戶    
  100.         User user = (User) session.getAttribute(WebConstants.CURRENT_USER);    
  101.         //獲取請求ip    
  102.         String ip = request.getRemoteAddr();    
  103.         //獲取用戶請求方法的參數并序列化為JSON格式字符串    
  104.         String params = "";    
  105.          if (joinPoint.getArgs() !=  null && joinPoint.getArgs().length > 0) {    
  106.              for ( int i = 0; i < joinPoint.getArgs().length; i++) {    
  107.                 params += JSONUtil.toJsonString(joinPoint.getArgs()[i]) + ";";    
  108.             }    
  109.         }    
  110.          try {    
  111.               /*========控制臺輸出=========*/    
  112.             System.out.println("=====異常通知開始=====");    
  113.             System.out.println("異常代碼:" + e.getClass().getName());    
  114.             System.out.println("異常信息:" + e.getMessage());    
  115.             System.out.println("異常方法:" + (joinPoint.getTarget().getClass().getName() + "." + joinPoint.getSignature().getName() + "()"));    
  116.             System.out.println("方法描述:" + getServiceMthodDescription(joinPoint));    
  117.             System.out.println("請求人:" + user.getName());    
  118.             System.out.println("請求IP:" + ip);    
  119.             System.out.println("請求參數:" + params);    
  120.                /*==========數據庫日志=========*/    
  121.             Log log = SpringContextHolder.getBean("logxx");    
  122.             log.setDescription(getServiceMthodDescription(joinPoint));    
  123.             log.setExceptionCode(e.getClass().getName());    
  124.             log.setType("1");    
  125.             log.setExceptionDetail(e.getMessage());    
  126.             log.setMethod((joinPoint.getTarget().getClass().getName() + "." + joinPoint.getSignature().getName() + "()"));    
  127.             log.setParams(params);    
  128.             log.setCreateBy(user);    
  129.             log.setCreateDate(DateUtil.getCurrentDate());    
  130.             log.setRequestIp(ip);    
  131.             //保存數據庫    
  132.             logService.add(log);    
  133.             System.out.println("=====異常通知結束=====");    
  134.         }  catch (Exception ex) {    
  135.             //記錄本地異常日志    
  136.             logger.error("==異常通知異常==");    
  137.             logger.error("異常信息:{}", ex.getMessage());    
  138.         }    
  139.          /*==========記錄本地異常日志==========*/    
  140.         logger.error("異常方法:{}異常代碼:{}異常信息:{}參數:{}", joinPoint.getTarget().getClass().getName() + joinPoint.getSignature().getName(), e.getClass().getName(), e.getMessage(), params);    
  141.     
  142.     }    
  143.     
  144.     
  145.     /**  
  146.      * 獲取注解中對方法的描述信息 用于service層注解  
  147.      *  
  148.      * @param joinPoint 切點  
  149.      * @return 方法描述  
  150.      * @throws Exception  
  151.      */    
  152.      public  static String getServiceMthodDescription(JoinPoint joinPoint)    
  153.              throws Exception {    
  154.         String targetName = joinPoint.getTarget().getClass().getName();    
  155.         String methodName = joinPoint.getSignature().getName();    
  156.         Object[] arguments = joinPoint.getArgs();    
  157.         Class targetClass = Class.forName(targetName);    
  158.         Method[] methods = targetClass.getMethods();    
  159.         String description = "";    
  160.          for (Method method : methods) {    
  161.              if (method.getName().equals(methodName)) {    
  162.                 Class[] clazzs = method.getParameterTypes();    
  163.                  if (clazzs.length == arguments.length) {    
  164.                     description = method.getAnnotation(SystemServiceLog. class).description();    
  165.                      break;    
  166.                 }    
  167.             }    
  168.         }    
  169.          return description;    
  170.     }    
  171.     
  172.     /**  
  173.      * 獲取注解中對方法的描述信息 用于Controller層注解  
  174.      *  
  175.      * @param joinPoint 切點  
  176.      * @return 方法描述  
  177.      * @throws Exception  
  178.      */    
  179.      public  static String getControllerMethodDescription(JoinPoint joinPoint)  throws Exception {    
  180.         String targetName = joinPoint.getTarget().getClass().getName();    
  181.         String methodName = joinPoint.getSignature().getName();    
  182.         Object[] arguments = joinPoint.getArgs();    
  183.         Class targetClass = Class.forName(targetName);    
  184.         Method[] methods = targetClass.getMethods();    
  185.         String description = "";    
  186.          for (Method method : methods) {    
  187.              if (method.getName().equals(methodName)) {    
  188.                 Class[] clazzs = method.getParameterTypes();    
  189.                  if (clazzs.length == arguments.length) {    
  190.                     description = method.getAnnotation(SystemControllerLog. class).description();    
  191.                      break;    
  192.                 }    
  193.             }    
  194.         }    
  195.          return description;    
  196.     }    
  197. }    



 第三步把Controller的代理權交給cglib


在實例化applicationContext的時候需要加上


 

xml代碼 
  1. <!-- 啟動對@AspectJ注解的支持 -->  
  2. <aop:aspectj-autoproxy/>  

 在調用Controller的時候AOP發揮作用所以在SpringMVC的配置文件里加上


Xml代碼 
  1. <!--通知spring使用cglib而不是jdk的來生成代理方法 AOP可以攔截到Controller->  
  2. <aop:aspectj-autoproxy proxy-target-class="true" />  

 第四步使用

 

Controller層的使用

Java代碼

 

[java] view plaincopy
  1. /**  
  2.     * 刪除用戶  
  3.     *  
  4.     * @param criteria 條件  
  5.     * @param id       id  
  6.     * @param model    模型  
  7.     * @return 數據列表  
  8.     */    
  9.    @RequestMapping(value = "/delete")    
  10.    //此處為記錄AOP攔截Controller記錄用戶操作    
  11.    @SystemControllerLog(description = "刪除用戶")    
  12.     public String del(Criteria criteria, String id, Model model, HttpSession session) {    
  13.         try {    
  14.            User user = (User) session.getAttribute(WebConstants.CURRENT_USER);    
  15.             if ( null != user) {    
  16.                 if (user.getId().equals(id)) {    
  17.                    msg = "您不可以刪除自己!";    
  18.                    criteria = userService.selectByCriteriaPagination(criteria);    
  19.                }  else {    
  20.                    //刪除數據并查詢出數據    
  21.                    criteria = userService.delete(id, criteria);    
  22.                    msg = "刪除成功!";    
  23.                }    
  24.            }    
  25.        }  catch (Exception e) {    
  26.            msg = "刪除失敗!";    
  27.        }  finally {    
  28.            model.addAttribute("msg", msg);    
  29.            model.addAttribute("criteria", criteria);    
  30.        }    
  31.        //跳轉列表頁    
  32.         return "user/list";    
  33.    }    


 Service層的使用


 

[java] view plaincopy在CODE上查看代碼片
/**  
  •     * 按照分頁查詢  
  •     * @param criteria  
  •     * @return  
  •     */    
  •    //此處為AOP攔截Service記錄異常信息。方法不需要加try-catch    
  •    @SystemServiceLog(description = "查詢用戶")    
  •     public Criteria<User> selectByCriteriaPagination(Criteria<User> criteria)    
  •    {    
  •        criteria.getList().get(0).getAccount();    
  •        //查詢總數    
  •         long total=userMapper.countByCriteria(criteria);    
  •        //設置總數    
  •        criteria.setRowCount(total);    
  •        criteria.setList(userMapper.selectByCriteriaPagination(criteria));    
  •         return  criteria;    
  •    }    

    效果圖

     

    用戶操作:


     異常



    發表評論 共有條評論
    用戶名: 密碼:
    驗證碼: 匿名發表
    亚洲香蕉成人av网站在线观看_欧美精品成人91久久久久久久_久久久久久久久久久亚洲_热久久视久久精品18亚洲精品_国产精自产拍久久久久久_亚洲色图国产精品_91精品国产网站_中文字幕欧美日韩精品_国产精品久久久久久亚洲调教_国产精品久久一区_性夜试看影院91社区_97在线观看视频国产_68精品久久久久久欧美_欧美精品在线观看_国产精品一区二区久久精品_欧美老女人bb
    久热精品视频在线观看| 性欧美xxxx| 清纯唯美亚洲激情| 国产精品亚洲视频在线观看| 久久久久五月天| 国产91亚洲精品| 久久久精品视频成人| 国产精品小说在线| 日韩精品久久久久久福利| 久久久久久亚洲精品| 亚州av一区二区| 久久久国产精品免费| 精品国产一区二区三区在线观看| 国产97在线亚洲| 国产精欧美一区二区三区| 久久久黄色av| 亚洲国产私拍精品国模在线观看| 亚洲国产精品系列| 热久久视久久精品18亚洲精品| 欧美电影免费观看高清| 黑人巨大精品欧美一区二区三区| 亚洲成人av在线播放| 亚洲成**性毛茸茸| 中文字幕亚洲天堂| 亚洲色图日韩av| 美女黄色丝袜一区| 国产成人免费91av在线| 欧洲永久精品大片ww免费漫画| 68精品国产免费久久久久久婷婷| 亚洲欧美中文在线视频| 日本高清+成人网在线观看| 日韩风俗一区 二区| 欧美高清视频一区二区| 青草热久免费精品视频| 欧美视频中文在线看| 91国产视频在线播放| 国产精品福利在线观看网址| 欧美福利在线观看| 亚洲精品欧美极品| 国产精品免费视频久久久| 亚洲色图第一页| 亚洲免费精彩视频| 自拍偷拍免费精品| 91精品国产91久久久| 深夜福利国产精品| 欧美疯狂性受xxxxx另类| 久久精品这里热有精品| 日本高清视频一区| 亚洲天堂男人天堂女人天堂| 黄色精品在线看| 国产精品入口尤物| 久久久91精品国产一区不卡| 亚洲精品短视频| 欧美乱妇高清无乱码| 日韩久久免费视频| 久久av中文字幕| 国产精品99蜜臀久久不卡二区| 精品一区二区三区四区| 丝袜美腿亚洲一区二区| 午夜精品久久久久久99热软件| 亚洲无限乱码一二三四麻| 亚洲欧美日韩国产成人| 中文一区二区视频| 精品日韩视频在线观看| 欧美精品久久久久久久免费观看| 日本精品在线视频| 欧美成人一区在线| 久久精品国产2020观看福利| 精品国内自产拍在线观看| 自拍视频国产精品| 日韩激情第一页| 国产一区二区欧美日韩| 亚洲精品国产福利| 国产va免费精品高清在线| 91精品国产高清久久久久久| 中文字幕精品在线视频| 亚洲自拍另类欧美丝袜| 丁香五六月婷婷久久激情| 4444欧美成人kkkk| 国产精彩精品视频| 亚洲一区二区中文| 国产精品久久久久久久久久三级| 久久精品美女视频网站| 亚洲在线观看视频网站| 国产亚洲欧美日韩一区二区| 久久综合伊人77777| 国产日韩视频在线观看| xxav国产精品美女主播| 国产91ⅴ在线精品免费观看| 久久精品亚洲94久久精品| 久久久国产一区| www.日韩不卡电影av| 久久久久久com| 久久精品久久久久电影| 亚洲国产精品成人精品| 成人免费视频网址| 精品视频久久久久久久| 亚洲欧洲在线免费| 欧美成人精品不卡视频在线观看| 一区二区三区国产视频| 日韩在线观看成人| 精品亚洲精品福利线在观看| 亚洲欧美一区二区激情| 亚洲天堂av在线免费| 91香蕉电影院| 国产亚洲精品va在线观看| 久久亚洲精品小早川怜子66| 色婷婷综合久久久久| 美女性感视频久久久| 国产精品久在线观看| 国产日韩综合一区二区性色av| 亚洲综合日韩在线| 欧美精品在线免费播放| 欧美夫妻性生活视频| 亚洲jizzjizz日本少妇| 麻豆成人在线看| 国产欧美一区二区三区视频| 欧美日韩中文字幕综合视频| 国产精品观看在线亚洲人成网| 日本久久久久久久久久久| 91国在线精品国内播放| 97香蕉久久夜色精品国产| 欧美在线国产精品| 亚洲一区二区三区四区视频| 久久男人av资源网站| 久久免费精品日本久久中文字幕| 国产精品自产拍在线观看| 国产成人精品a视频一区www| 久久久久99精品久久久久| 欧美大奶子在线| 日韩免费精品视频| 日韩美女视频免费看| 久久乐国产精品| 亚洲精品久久久久中文字幕欢迎你| 欧美人交a欧美精品| 91青草视频久久| 亚洲午夜性刺激影院| 国产精品一区二区3区| 日韩视频在线免费| 亚洲欧美一区二区三区久久| 久久久免费电影| 国产精品h在线观看| 国产成+人+综合+亚洲欧美丁香花| 国产一区二区三区在线观看视频| 精品国产一区av| 国产精品吴梦梦| 日韩欧美在线视频日韩欧美在线视频| 亚洲深夜福利在线| 国产精品爱啪在线线免费观看| 在线精品国产成人综合| 久久久久久亚洲精品不卡| 一本色道久久综合狠狠躁篇的优点| 欧美成人精品在线观看| 久久激情五月丁香伊人| 日韩精品在线免费观看视频| 午夜精品一区二区三区av| 中文字幕亚洲欧美日韩2019| www国产精品com| 午夜剧场成人观在线视频免费观看| 国产精品久久久久999| 亚洲美女www午夜| 国产99久久精品一区二区 夜夜躁日日躁| 精品国产一区二区三区在线观看| 欧美肥臀大乳一区二区免费视频|