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

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

springAOP自定義注解方式實現日志管理

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

今天繼續實現AOP,到這里我個人認為是最靈活,可擴展的方式了,就拿日志管理來說,用SPRing AOP 自定義注解形式實現日志管理。廢話不多說,直接開始?。?!

關于配置我還是的再說一遍。

 

applicationContext-mvc.xml中要添加的

     <mvc:annotation-driven />
     <!-- 激活組件掃描功能,在包com.gcx及其子包下面自動掃描通過注解配置的組件 -->
     <context:component-scan base-package="com.gcx" />

  

     <!-- 啟動對@aspectJ注解的支持 -->
     <!-- proxy-target-class等于true是強制使用cglib代理,proxy-target-class默認是false,如果你的類實現了接口 就走JDK代理,如果沒有,走cglib代理  -->
     <!-- 注:對于單利模式建議使用cglib代理,雖然JDK動態代理比cglib代理速度快,但性能不如cglib -->

     <!--如果不寫proxy-target-class="true"這句話也沒問題-->
     <aop:aspectj-autoproxy proxy-target-class="true"/>

     <!--切面-->
     <bean id="systemLogAspect" class="com.gcx.annotation.SystemLogAspect"></bean>

接下來開始編寫代碼。

     創建日志類實體

  1 public class SystemLog {  2     private String id;  3   4     private String description;  5   6     private String method;  7   8     private Long logType;  9  10     private String requestIp; 11  12     private String exceptioncode; 13  14     private String exceptionDetail; 15  16     private String params; 17  18     private String createBy; 19  20     private Date createDate; 21  22     public String getId() { 23         return id; 24     } 25  26     public void setId(String id) { 27         this.id = id == null ? null : id.trim(); 28     } 29  30     public String getDescription() { 31         return description; 32     } 33  34     public void setDescription(String description) { 35         this.description = description == null ? null : description.trim(); 36     } 37  38     public String getMethod() { 39         return method; 40     } 41  42     public void setMethod(String method) { 43         this.method = method == null ? null : method.trim(); 44     } 45  46     public Long getLogType() { 47         return logType; 48     } 49  50     public void setLogType(Long logType) { 51         this.logType = logType; 52     } 53  54     public String getRequestIp() { 55         return requestIp; 56     } 57  58     public void setRequestIp(String requestIp) { 59         this.requestIp = requestIp == null ? null : requestIp.trim(); 60     } 61  62     public String getExceptioncode() { 63         return exceptioncode; 64     } 65  66     public void setExceptioncode(String exceptioncode) { 67         this.exceptioncode = exceptioncode == null ? null : exceptioncode.trim(); 68     } 69  70     public String getExceptionDetail() { 71         return exceptionDetail; 72     } 73  74     public void setExceptionDetail(String exceptionDetail) { 75         this.exceptionDetail = exceptionDetail == null ? null : exceptionDetail.trim(); 76     } 77  78     public String getParams() { 79         return params; 80     } 81  82     public void setParams(String params) { 83         this.params = params == null ? null : params.trim(); 84     } 85  86     public String getCreateBy() { 87         return createBy; 88     } 89  90     public void setCreateBy(String createBy) { 91         this.createBy = createBy == null ? null : createBy.trim(); 92     } 93  94     public Date getCreateDate() { 95         return createDate; 96     } 97  98     public void setCreateDate(Date createDate) { 99         this.createDate = createDate;100     }101 }
View Code

     編寫dao接口

 1 package com.gcx.dao; 2  3 import com.gcx.entity.SystemLog; 4  5 public interface SystemLogMapper { 6     int deleteByPrimaryKey(String id); 7  8     int insert(SystemLog record); 9 10     int insertSelective(SystemLog record);11 12     SystemLog selectByPrimaryKey(String id);13 14     int updateByPrimaryKeySelective(SystemLog record);15 16     int updateByPrimaryKey(SystemLog record);17 }
View Code

    編寫service層

 1 package com.gcx.service; 2  3 import com.gcx.entity.SystemLog; 4  5 public interface SystemLogService { 6  7     int deleteSystemLog(String id); 8  9     int insert(SystemLog record);10     11     int insertTest(SystemLog record);12 13     SystemLog selectSystemLog(String id);14     15     int updateSystemLog(SystemLog record);16 }
View Code

   編寫service實現類serviceImpl

 1 package com.gcx.service.impl; 2  3 import javax.annotation.Resource; 4  5 import org.springframework.stereotype.Service; 6  7 import com.gcx.annotation.Log; 8 import com.gcx.dao.SystemLogMapper; 9 import com.gcx.entity.SystemLog;10 import com.gcx.service.SystemLogService;11 12 @Service("systemLogService")13 public class SystemLogServiceImpl implements SystemLogService {14 15     @Resource16     private SystemLogMapper systemLogMapper;17     18     @Override19     public int deleteSystemLog(String id) {20         21         return systemLogMapper.deleteByPrimaryKey(id);22     }23 24     @Override25     26     public int insert(SystemLog record) {27         28         return systemLogMapper.insertSelective(record);29     }30 31     @Override32     public SystemLog selectSystemLog(String id) {33         34         return systemLogMapper.selectByPrimaryKey(id);35     }36 37     @Override38     public int updateSystemLog(SystemLog record) {39         40         return systemLogMapper.updateByPrimaryKeySelective(record);41     }42 43     @Override44     public int insertTest(SystemLog record) {45         46         return systemLogMapper.insert(record);47     }48 49 }
View Code

到這里基本程序編寫完畢

下面開始自定義注解

 1 package com.gcx.annotation; 2  3 import java.lang.annotation.*; 4  5 @Target({ElementType.PARAMETER, ElementType.METHOD})   6 @Retention(RetentionPolicy.RUNTIME)   7 @Documented   8 public @interface Log { 9 10     /** 要執行的操作類型比如:add操作 **/  11     public String OperationType() default "";  12      13     /** 要執行的具體操作比如:添加用戶 **/  14     public String operationName() default "";15 }

 

下面編寫切面

  1 package com.gcx.annotation;  2   3 import java.lang.reflect.Method;  4 import java.util.Date;  5 import java.util.UUID;  6   7 import javax.annotation.Resource;  8 import javax.servlet.http.HttpServletRequest;  9 import javax.servlet.http.Httpsession; 10  11 import org.aspectj.lang.JoinPoint; 12 import org.aspectj.lang.ProceedingJoinPoint; 13 import org.aspectj.lang.annotation.After; 14 import org.aspectj.lang.annotation.AfterReturning; 15 import org.aspectj.lang.annotation.AfterThrowing; 16 import org.aspectj.lang.annotation.Around; 17 import org.aspectj.lang.annotation.Aspect; 18 import org.aspectj.lang.annotation.Before; 19 import org.aspectj.lang.annotation.Pointcut; 20 import org.slf4j.Logger; 21 import org.slf4j.LoggerFactory; 22 import org.springframework.stereotype.Component; 23  24 import com.gcx.entity.SystemLog; 25 import com.gcx.entity.User; 26 import com.gcx.service.SystemLogService; 27 import com.gcx.util.JsonUtil; 28  29 /** 30  * @author 楊建  31  * @E-mail: email 32  * @version 創建時間:2015-10-19 下午4:29:05 33  * @desc 切點類  34  */ 35  36 @Aspect 37 @Component 38 public class SystemLogAspect { 39  40     //注入Service用于把日志保存數據庫   41     @Resource  //這里我用resource注解,一般用的是@Autowired,他們的區別如有時間我會在后面的博客中來寫 42     private SystemLogService systemLogService;   43      44     private  static  final Logger logger = LoggerFactory.getLogger(SystemLogAspect. class);   45      46     //Controller層切點   47     @Pointcut("execution (* com.gcx.controller..*.*(..))")   48     public  void controllerAspect() {   49     }   50      51     /**  52      * 前置通知 用于攔截Controller層記錄用戶的操作  53      *  54      * @param joinPoint 切點  55      */  56     @Before("controllerAspect()") 57     public void doBefore(JoinPoint joinPoint) { 58         System.out.println("==========執行controller前置通知==============="); 59         if(logger.isInfoEnabled()){ 60             logger.info("before " + joinPoint); 61         } 62     }     63      64     //配置controller環繞通知,使用在方法aspect()上注冊的切入點 65       @Around("controllerAspect()") 66       public void around(JoinPoint joinPoint){ 67           System.out.println("==========開始執行controller環繞通知==============="); 68           long start = System.currentTimeMillis(); 69           try { 70               ((ProceedingJoinPoint) joinPoint).proceed(); 71               long end = System.currentTimeMillis(); 72               if(logger.isInfoEnabled()){ 73                   logger.info("around " + joinPoint + "/tUse time : " + (end - start) + " ms!"); 74               } 75               System.out.println("==========結束執行controller環繞通知==============="); 76           } catch (Throwable e) { 77               long end = System.currentTimeMillis(); 78               if(logger.isInfoEnabled()){ 79                   logger.info("around " + joinPoint + "/tUse time : " + (end - start) + " ms with exception : " + e.getMessage()); 80               } 81           } 82       } 83      84     /**  85      * 后置通知 用于攔截Controller層記錄用戶的操作  86      *  87      * @param joinPoint 切點  88      */   89     @After("controllerAspect()")   90     public  void after(JoinPoint joinPoint) {   91    92        /* HttpServletRequest request = ((ServletRequestAttributes) RequestContextHolder.getRequestAttributes()).getRequest();   93         HttpSession session = request.getSession();  */ 94         //讀取session中的用戶   95        // User user = (User) session.getAttribute("user");   96         //請求的IP   97         //String ip = request.getRemoteAddr(); 98         User user = new User(); 99         user.setId(1);100         user.setName("張三");101         String ip = "127.0.0.1";102          try {  103             104             String targetName = joinPoint.getTarget().getClass().getName();  105             String methodName = joinPoint.getSignature().getName();  106             Object[] arguments = joinPoint.getArgs();  107             Class targetClass = Class.forName(targetName);  108             Method[] methods = targetClass.getMethods();109             String operationType = "";110             String operationName = "";111              for (Method method : methods) {  112                  if (method.getName().equals(methodName)) {  113                     Class[] clazzs = method.getParameterTypes();  114                      if (clazzs.length == arguments.length) {  115                          operationType = method.getAnnotation(Log.class).operationType();116                          operationName = method.getAnnotation(Log.class).operationName();117                          break;  118                     }  119                 }  120             }121             //*========控制臺輸出=========*//  122             System.out.println("=====controller后置通知開始=====");  123             System.out.println("請求方法:" + (joinPoint.getTarget().getClass().getName() + "." + joinPoint.getSignature().getName() + "()")+"."+operationType);  124             System.out.println("方法描述:" + operationName);  125             System.out.println("請求人:" + user.getName());  126             System.out.println("請求IP:" + ip);  127             //*========數據庫日志=========*//  128             SystemLog log = new SystemLog();  129             log.setId(UUID.randomUUID().toString());130             log.setDescription(operationName);  131             log.setMethod((joinPoint.getTarget().getClass().getName() + "." + joinPoint.getSignature().getName() + "()")+"."+operationType);  132             log.setLogType((long)0);  133             log.setRequestIp(ip);  134             log.setExceptioncode( null);  135             log.setExceptionDetail( null);  136             log.setParams( null);  137             log.setCreateBy(user.getName());  138             log.setCreateDate(new Date());  139             //保存數據庫  140             systemLogService.insert(log);  141             System.out.println("=====controller后置通知結束=====");  142         }  catch (Exception e) {  143             //記錄本地異常日志  144             logger.error("==后置通知異常==");  145             logger.error("異常信息:{}", e.getMessage());  146         }  147     } 148     149     //配置后置返回通知,使用在方法aspect()上注冊的切入點150       @AfterReturning("controllerAspect()")151       public void afterReturn(JoinPoint joinPoint){152           System.out.println("=====執行controller后置返回通知=====");  153               if(logger.isInfoEnabled()){154                   logger.info("afterReturn " + joinPoint);155               }156       }157     158     /** 159      * 異常通知 用于攔截記錄異常日志 160      * 161      * @param joinPoint 162      * @param e 163      */  164      @AfterThrowing(pointcut = "controllerAspect()", throwing="e")  165      public  void doAfterThrowing(JoinPoint joinPoint, Throwable e) {  166         /*HttpServletRequest request = ((ServletRequestAttributes) RequestContextHolder.getRequestAttributes()).getRequest();  167         HttpSession session = request.getSession();  168         //讀取session中的用戶  169         User user = (User) session.getAttribute(WebConstants.CURRENT_USER);  170         //獲取請求ip  171         String ip = request.getRemoteAddr(); */ 172         //獲取用戶請求方法的參數并序列化為JSON格式字符串  173         174         User user = new User();175         user.setId(1);176         user.setName("張三");177         String ip = "127.0.0.1";178         179         String params = "";  180          if (joinPoint.getArgs() !=  null && joinPoint.getArgs().length > 0) {  181              for ( int i = 0; i < joinPoint.getArgs().length; i++) {  182                 params += JsonUtil.getJsonStr(joinPoint.getArgs()[i]) + ";";  183             }  184         }  185          try {  186              187              String targetName = joinPoint.getTarget().getClass().getName();  188              String methodName = joinPoint.getSignature().getName();  189              Object[] arguments = joinPoint.getArgs();  190              Class targetClass = Class.forName(targetName);  191              Method[] methods = targetClass.getMethods();192              String operationType = "";193              String operationName = "";194               for (Method method : methods) {  195                   if (method.getName().equals(methodName)) {  196                      Class[] clazzs = method.getParameterTypes();  197                       if (clazzs.length == arguments.length) {  198                           operationType = method.getAnnotation(Log.class).operationType();199                           operationName = method.getAnnotation(Log.class).operationName();200                           break;  201                      }  202                  }  203              }204              /*========控制臺輸出=========*/  205             System.out.println("=====異常通知開始=====");  206             System.out.println("異常代碼:" + e.getClass().getName());  207             System.out.println("異常信息:" + e.getMessage());  208             System.out.println("異常方法:" + (joinPoint.getTarget().getClass().getName() + "." + joinPoint.getSignature().getName() + "()")+"."+operationType);  209             System.out.println("方法描述:" + operationName);  210             System.out.println("請求人:" + user.getName());  211             System.out.println("請求IP:" + ip);  212             System.out.println("請求參數:" + params);  213                /*==========數據庫日志=========*/  214             SystemLog log = new SystemLog();215             log.setId(UUID.randomUUID().toString());216             log.setDescription(operationName);  217             log.setExceptioncode(e.getClass().getName());  218             log.setLogType((long)1);  219             log.setExceptionDetail(e.getMessage());  220             log.setMethod((joinPoint.getTarget().getClass().getName() + "." + joinPoint.getSignature().getName() + "()"));  221             log.setParams(params);  222             log.setCreateBy(user.getName());  223             log.setCreateDate(new Date());  224             log.setRequestIp(ip);  225             //保存數據庫  226             systemLogService.insert(log);  227             System.out.println("=====異常通知結束=====");  228         }  catch (Exception ex) {  229             //記錄本地異常日志  230             logger.error("==異常通知異常==");  231             logger.error("異常信息:{}", ex.getMessage());  232         }  233          /*==========記錄本地異常日志==========*/  234         logger.error("異常方法:{}異常代碼:{}異常信息:{}參數:{}", joinPoint.getTarget().getClass().getName() + joinPoint.getSignature().getName(), e.getClass().getName(), e.getMessage(), params);  235   236     }  237     238 }

 我這里寫的比較全,前置通知,環繞通知,后置通知,異常通知,后置飯后通知,都寫上了,在我們實際編寫中不寫全也沒事,我習慣上把記錄日志的邏輯寫在后置通知里面,我看網上也有些在前置通知里面的,但我感覺寫在后置通知里比較好。

下面開始在controller中加入自定義的注解??!

 1 package com.gcx.controller; 2  3 import org.springframework.beans.factory.annotation.Autowired; 4 import org.springframework.stereotype.Controller; 5 import org.springframework.web.bind.annotation.RequestMapping; 6  7 import com.gcx.annotation.Log; 8 import com.gcx.service.UserService; 9 10 @Controller11 @RequestMapping("userController")12 public class UserController {13 14     @Autowired15     private UserService userService;16     17     @RequestMapping("testAOP")18     @Log(operationType="add操作:",operationName="添加用戶")  19     public void testAOP(String userName,String passWord){        20         userService.addUser(userName, password);21     }22 }

下面編寫測試類

1 @Test2     public void testAOP1(){3         //啟動Spring容器        4         ApplicationContext ctx = new ClassPathXmlApplicationContext(new String[]{"classpath:applicationContext-mvc.xml","classpath:applicationContext-dataSource.xml"});5         //獲取service或controller組件6         UserController userController = (UserController) ctx.getBean("userController");7         userController.testAOP("zhangsan", "123456");8     }9     

數據庫數據:

我原本想寫兩個切點,一個是service層,一個是controller層,service層是用來記錄異常信息的日志,而controller層的是用來記錄功能的日志,運行結果如下。    

這樣做的話不知道在實際的項目中運行效率好不好,在這里請看到博客的大牛給點建議!!


發表評論 共有條評論
用戶名: 密碼:
驗證碼: 匿名發表
亚洲香蕉成人av网站在线观看_欧美精品成人91久久久久久久_久久久久久久久久久亚洲_热久久视久久精品18亚洲精品_国产精自产拍久久久久久_亚洲色图国产精品_91精品国产网站_中文字幕欧美日韩精品_国产精品久久久久久亚洲调教_国产精品久久一区_性夜试看影院91社区_97在线观看视频国产_68精品久久久久久欧美_欧美精品在线观看_国产精品一区二区久久精品_欧美老女人bb
色婷婷亚洲mv天堂mv在影片| 日韩av一卡二卡| 欧美精品电影在线| 九九视频这里只有精品| 欧美特黄级在线| 国产精品1区2区在线观看| 欧美美最猛性xxxxxx| 久久成人人人人精品欧| 国产精品久久久久久久久久久新郎| 久久久久成人精品| 欧美激情一级二级| 亚洲一区二区自拍| 亚洲最大福利网站| 欧美另类极品videosbestfree| 久久夜色精品国产欧美乱| 亚洲欧美综合区自拍另类| 国产精品自产拍高潮在线观看| 亚洲综合日韩在线| 欧美色视频日本版| 成人做爽爽免费视频| 国产视频999| 国产精品亚洲视频在线观看| 久久久精品2019中文字幕神马| 97国产精品免费视频| 久久久成人精品视频| 亚洲美女av在线播放| 国产极品精品在线观看| 日韩av快播网址| 日韩最新中文字幕电影免费看| 亚洲欧美在线一区| 奇门遁甲1982国语版免费观看高清| 亚洲日本成人女熟在线观看| 亚洲第一视频网站| 国产精品∨欧美精品v日韩精品| 国产精品视频公开费视频| 欧美自拍大量在线观看| 日韩av网站导航| 成人黄色短视频在线观看| 亚洲一区二区三区777| 成人久久一区二区三区| 亚洲www在线观看| 日韩精品免费在线视频观看| 在线播放精品一区二区三区| 国产一区二区三区直播精品电影| 中文字幕亚洲综合| 成人国产精品色哟哟| 欧美午夜片欧美片在线观看| 91精品国产777在线观看| 精品视频久久久久久| 久久久免费精品| 欧洲一区二区视频| 国产亚洲欧美日韩美女| 欧美成人午夜剧场免费观看| 亚洲专区在线视频| 欧美国产日韩xxxxx| 亚洲成人动漫在线播放| 最近2019中文免费高清视频观看www99| 日韩欧美一区二区三区久久| 成人在线视频网站| 亚洲欧美中文日韩在线v日本| 亚洲女成人图区| 日韩av在线网| 久久久久久久色| 欧美亚洲国产另类| 国产精品国产三级国产aⅴ浪潮| 九九热这里只有在线精品视| 成人网页在线免费观看| 国产精品自产拍在线观看中文| 国产偷亚洲偷欧美偷精品| 久久视频这里只有精品| 51色欧美片视频在线观看| 日韩在线不卡视频| 黄网动漫久久久| 97色在线视频观看| 欧美日韩在线免费观看| 国产www精品| 热门国产精品亚洲第一区在线| 一本一本久久a久久精品综合小说| 日韩精品中文字幕视频在线| 精品久久久91| 精品欧美aⅴ在线网站| 成人黄色影片在线| 成人h视频在线| 黑人巨大精品欧美一区二区免费| 色综合久久88色综合天天看泰| 日本19禁啪啪免费观看www| 国产亚洲精品成人av久久ww| 国产成人精品一区二区三区| 美日韩精品视频免费看| 欧美日韩免费在线| 国产不卡av在线免费观看| 91探花福利精品国产自产在线| 亚洲综合视频1区| 国产精品永久免费视频| 国产suv精品一区二区三区88区| 茄子视频成人在线| 亚洲人午夜色婷婷| 91精品综合久久久久久五月天| 亚洲国产精品久久久久秋霞不卡| 精品色蜜蜜精品视频在线观看| 热久久99这里有精品| 亚洲国产成人精品久久久国产成人一区| 狠狠久久五月精品中文字幕| 日本成熟性欧美| 成人国产亚洲精品a区天堂华泰| 亚洲美女www午夜| 久久视频国产精品免费视频在线| 国产精品美女免费看| 一区二区三区美女xx视频| 亚洲电影av在线| 欧美精品久久久久a| 精品亚洲va在线va天堂资源站| 成人观看高清在线观看免费| 一区二区三区久久精品| 欧美激情亚洲视频| 欧美专区在线播放| 91网在线免费观看| 亚洲人成网站免费播放| 91视频免费网站| 久久视频在线看| 狠狠干狠狠久久| 久久躁狠狠躁夜夜爽| 亚洲欧美福利视频| 亚洲爱爱爱爱爱| 国产精品极品美女粉嫩高清在线| 国产美女精品视频免费观看| 亚洲xxxxx性| 欧美国产精品人人做人人爱| 亚洲国产精品网站| 日韩成人在线视频网站| 欧美在线视频一二三| 热99在线视频| 国模私拍视频一区| 国产丝袜一区二区| 日韩激情视频在线| 精品成人久久av| 中文字幕日韩精品在线观看| 欧美在线国产精品| 精品久久久久久久中文字幕| 中文字幕在线成人| 亚洲一区二区中文字幕| 97视频在线观看亚洲| 亚洲女人被黑人巨大进入al| 久久久久国产精品www| 欧美插天视频在线播放| 国产精品福利小视频| 欧美亚洲另类制服自拍| 一区二区成人av| 久久亚洲精品一区二区| 伊是香蕉大人久久| 日韩中文在线观看| 美日韩丰满少妇在线观看| 性色av香蕉一区二区| 国产热re99久久6国产精品| 中文字幕v亚洲ⅴv天堂| 国产精品久久久久久网站| 日韩经典中文字幕在线观看| 亚洲乱码一区二区| 欧美激情国产日韩精品一区18| 亚洲欧美制服第一页| 国产精品中文字幕在线| 国产精品美女呻吟| 色青青草原桃花久久综合| 国产精品久久久久久久av大片|