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

首頁 > 開發 > Java > 正文

spring AOP自定義注解方式實現日志管理的實例講解

2024-07-13 10:17:08
字體:
來源:轉載
供稿:網友

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

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

在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>

接下來開始編寫代碼。

創建日志類實體

public class SystemLog {  private String id;  private String description;  private String method;  private Long logType;  private String requestIp;  private String exceptioncode;  private String exceptionDetail;  private String params;  private String createBy;  private Date createDate;  public String getId() {    return id;  }  public void setId(String id) {    this.id = id == null ? null : id.trim();  }  public String getDescription() {    return description;  }  public void setDescription(String description) {    this.description = description == null ? null : description.trim();  }  public String getMethod() {    return method;  }  public void setMethod(String method) {    this.method = method == null ? null : method.trim();  }  public Long getLogType() {    return logType;  }  public void setLogType(Long logType) {    this.logType = logType;  }  public String getRequestIp() {    return requestIp;  }  public void setRequestIp(String requestIp) {    this.requestIp = requestIp == null ? null : requestIp.trim();  }  public String getExceptioncode() {    return exceptioncode;  }  public void setExceptioncode(String exceptioncode) {    this.exceptioncode = exceptioncode == null ? null : exceptioncode.trim();  }  public String getExceptionDetail() {    return exceptionDetail;  }  public void setExceptionDetail(String exceptionDetail) {    this.exceptionDetail = exceptionDetail == null ? null : exceptionDetail.trim();  }  public String getParams() {    return params;  }  public void setParams(String params) {    this.params = params == null ? null : params.trim();  }  public String getCreateBy() {    return createBy;  }  public void setCreateBy(String createBy) {    this.createBy = createBy == null ? null : createBy.trim();  }  public Date getCreateDate() {    return createDate;  }  public void setCreateDate(Date createDate) {    this.createDate = createDate;  }}

編寫dao接口

package com.gcx.dao;import com.gcx.entity.SystemLog;public interface SystemLogMapper {  int deleteByPrimaryKey(String id);  int insert(SystemLog record);  int insertSelective(SystemLog record);  SystemLog selectByPrimaryKey(String id);  int updateByPrimaryKeySelective(SystemLog record);  int updateByPrimaryKey(SystemLog record);}

編寫service層

package com.gcx.service;import com.gcx.entity.SystemLog;public interface SystemLogService {  int deleteSystemLog(String id);  int insert(SystemLog record);    int insertTest(SystemLog record);  SystemLog selectSystemLog(String id);    int updateSystemLog(SystemLog record);}

編寫service實現類serviceImpl

package com.gcx.service.impl;import javax.annotation.Resource;import org.springframework.stereotype.Service;import com.gcx.annotation.Log;import com.gcx.dao.SystemLogMapper;import com.gcx.entity.SystemLog;import com.gcx.service.SystemLogService;@Service("systemLogService")public class SystemLogServiceImpl implements SystemLogService {  @Resource  private SystemLogMapper systemLogMapper;    @Override  public int deleteSystemLog(String id) {        return systemLogMapper.deleteByPrimaryKey(id);  }  @Override    public int insert(SystemLog record) {        return systemLogMapper.insertSelective(record);  }  @Override  public SystemLog selectSystemLog(String id) {        return systemLogMapper.selectByPrimaryKey(id);  }  @Override  public int updateSystemLog(SystemLog record) {        return systemLogMapper.updateByPrimaryKeySelective(record);  }  @Override  public int insertTest(SystemLog record) {        return systemLogMapper.insert(record);  }}

到這里基本程序編寫完畢

下面開始自定義注解

package com.gcx.annotation;import java.lang.annotation.*;@Target({ElementType.PARAMETER, ElementType.METHOD}) @Retention(RetentionPolicy.RUNTIME) @Documented public @interface Log {  /** 要執行的操作類型比如:add操作 **/   public String operationType() default "";      /** 要執行的具體操作比如:添加用戶 **/   public String operationName() default "";}

下面編寫切面

package com.gcx.annotation;import java.lang.reflect.Method;import java.util.Date;import java.util.UUID;import javax.annotation.Resource;import javax.servlet.http.HttpServletRequest;import javax.servlet.http.HttpSession;import org.aspectj.lang.JoinPoint;import org.aspectj.lang.ProceedingJoinPoint;import org.aspectj.lang.annotation.After;import org.aspectj.lang.annotation.AfterReturning;import org.aspectj.lang.annotation.AfterThrowing;import org.aspectj.lang.annotation.Around;import org.aspectj.lang.annotation.Aspect;import org.aspectj.lang.annotation.Before;import org.aspectj.lang.annotation.Pointcut;import org.slf4j.Logger;import org.slf4j.LoggerFactory;import org.springframework.stereotype.Component;import com.gcx.entity.SystemLog;import com.gcx.entity.User;import com.gcx.service.SystemLogService;import com.gcx.util.JsonUtil;/** * @author 楊建  * @E-mail: email * @version 創建時間:2015-10-19 下午4:29:05 * @desc 切點類  */@Aspect@Componentpublic class SystemLogAspect {  //注入Service用于把日志保存數據庫   @Resource //這里我用resource注解,一般用的是@Autowired,他們的區別如有時間我會在后面的博客中來寫  private SystemLogService systemLogService;     private static final Logger logger = LoggerFactory.getLogger(SystemLogAspect. class);     //Controller層切點   @Pointcut("execution (* com.gcx.controller..*.*(..))")   public void controllerAspect() {   }     /**    * 前置通知 用于攔截Controller層記錄用戶的操作    *    * @param joinPoint 切點    */   @Before("controllerAspect()")  public void doBefore(JoinPoint joinPoint) {    System.out.println("==========執行controller前置通知===============");    if(logger.isInfoEnabled()){      logger.info("before " + joinPoint);    }  }      //配置controller環繞通知,使用在方法aspect()上注冊的切入點   @Around("controllerAspect()")   public void around(JoinPoint joinPoint){     System.out.println("==========開始執行controller環繞通知===============");     long start = System.currentTimeMillis();     try {       ((ProceedingJoinPoint) joinPoint).proceed();       long end = System.currentTimeMillis();       if(logger.isInfoEnabled()){         logger.info("around " + joinPoint + "/tUse time : " + (end - start) + " ms!");       }       System.out.println("==========結束執行controller環繞通知===============");     } catch (Throwable e) {       long end = System.currentTimeMillis();       if(logger.isInfoEnabled()){         logger.info("around " + joinPoint + "/tUse time : " + (end - start) + " ms with exception : " + e.getMessage());       }     }   }    /**    * 后置通知 用于攔截Controller層記錄用戶的操作    *    * @param joinPoint 切點    */   @After("controllerAspect()")   public void after(JoinPoint joinPoint) {      /* HttpServletRequest request = ((ServletRequestAttributes) RequestContextHolder.getRequestAttributes()).getRequest();     HttpSession session = request.getSession(); */    //讀取session中的用戶     // User user = (User) session.getAttribute("user");     //請求的IP     //String ip = request.getRemoteAddr();    User user = new User();    user.setId(1);    user.setName("張三");    String ip = "127.0.0.1";     try {             String targetName = joinPoint.getTarget().getClass().getName();       String methodName = joinPoint.getSignature().getName();       Object[] arguments = joinPoint.getArgs();       Class targetClass = Class.forName(targetName);       Method[] methods = targetClass.getMethods();      String operationType = "";      String operationName = "";       for (Method method : methods) {          if (method.getName().equals(methodName)) {           Class[] clazzs = method.getParameterTypes();            if (clazzs.length == arguments.length) {              operationType = method.getAnnotation(Log.class).operationType();             operationName = method.getAnnotation(Log.class).operationName();             break;           }         }       }      //*========控制臺輸出=========*//       System.out.println("=====controller后置通知開始=====");       System.out.println("請求方法:" + (joinPoint.getTarget().getClass().getName() + "." + joinPoint.getSignature().getName() + "()")+"."+operationType);       System.out.println("方法描述:" + operationName);       System.out.println("請求人:" + user.getName());       System.out.println("請求IP:" + ip);       //*========數據庫日志=========*//       SystemLog log = new SystemLog();       log.setId(UUID.randomUUID().toString());      log.setDescription(operationName);       log.setMethod((joinPoint.getTarget().getClass().getName() + "." + joinPoint.getSignature().getName() + "()")+"."+operationType);       log.setLogType((long)0);       log.setRequestIp(ip);       log.setExceptioncode( null);       log.setExceptionDetail( null);       log.setParams( null);       log.setCreateBy(user.getName());       log.setCreateDate(new Date());       //保存數據庫       systemLogService.insert(log);       System.out.println("=====controller后置通知結束=====");     } catch (Exception e) {       //記錄本地異常日志       logger.error("==后置通知異常==");       logger.error("異常信息:{}", e.getMessage());     }   }     //配置后置返回通知,使用在方法aspect()上注冊的切入點   @AfterReturning("controllerAspect()")   public void afterReturn(JoinPoint joinPoint){     System.out.println("=====執行controller后置返回通知=====");        if(logger.isInfoEnabled()){         logger.info("afterReturn " + joinPoint);       }   }    /**    * 異常通知 用于攔截記錄異常日志    *    * @param joinPoint    * @param e    */    @AfterThrowing(pointcut = "controllerAspect()", throwing="e")    public void doAfterThrowing(JoinPoint joinPoint, Throwable e) {     /*HttpServletRequest request = ((ServletRequestAttributes) RequestContextHolder.getRequestAttributes()).getRequest();     HttpSession session = request.getSession();     //讀取session中的用戶     User user = (User) session.getAttribute(WebConstants.CURRENT_USER);     //獲取請求ip     String ip = request.getRemoteAddr(); */     //獲取用戶請求方法的參數并序列化為JSON格式字符串         User user = new User();    user.setId(1);    user.setName("張三");    String ip = "127.0.0.1";        String params = "";      if (joinPoint.getArgs() != null && joinPoint.getArgs().length > 0) {        for ( int i = 0; i < joinPoint.getArgs().length; i++) {         params += JsonUtil.getJsonStr(joinPoint.getArgs()[i]) + ";";       }     }      try {               String targetName = joinPoint.getTarget().getClass().getName();        String methodName = joinPoint.getSignature().getName();        Object[] arguments = joinPoint.getArgs();        Class targetClass = Class.forName(targetName);        Method[] methods = targetClass.getMethods();       String operationType = "";       String operationName = "";       for (Method method : methods) {          if (method.getName().equals(methodName)) {            Class[] clazzs = method.getParameterTypes();            if (clazzs.length == arguments.length) {              operationType = method.getAnnotation(Log.class).operationType();             operationName = method.getAnnotation(Log.class).operationName();             break;            }          }        }       /*========控制臺輸出=========*/       System.out.println("=====異常通知開始=====");       System.out.println("異常代碼:" + e.getClass().getName());       System.out.println("異常信息:" + e.getMessage());       System.out.println("異常方法:" + (joinPoint.getTarget().getClass().getName() + "." + joinPoint.getSignature().getName() + "()")+"."+operationType);       System.out.println("方法描述:" + operationName);       System.out.println("請求人:" + user.getName());       System.out.println("請求IP:" + ip);       System.out.println("請求參數:" + params);         /*==========數據庫日志=========*/       SystemLog log = new SystemLog();      log.setId(UUID.randomUUID().toString());      log.setDescription(operationName);       log.setExceptioncode(e.getClass().getName());       log.setLogType((long)1);       log.setExceptionDetail(e.getMessage());       log.setMethod((joinPoint.getTarget().getClass().getName() + "." + joinPoint.getSignature().getName() + "()"));       log.setParams(params);       log.setCreateBy(user.getName());       log.setCreateDate(new Date());       log.setRequestIp(ip);       //保存數據庫       systemLogService.insert(log);       System.out.println("=====異常通知結束=====");     } catch (Exception ex) {       //記錄本地異常日志       logger.error("==異常通知異常==");       logger.error("異常信息:{}", ex.getMessage());     }      /*==========記錄本地異常日志==========*/     logger.error("異常方法:{}異常代碼:{}異常信息:{}參數:{}", joinPoint.getTarget().getClass().getName() + joinPoint.getSignature().getName(), e.getClass().getName(), e.getMessage(), params);    }   }

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

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

package com.gcx.controller;import org.springframework.beans.factory.annotation.Autowired;import org.springframework.stereotype.Controller;import org.springframework.web.bind.annotation.RequestMapping;import com.gcx.annotation.Log;import com.gcx.service.UserService;@Controller@RequestMapping("userController")public class UserController {  @Autowired  private UserService userService;    @RequestMapping("testAOP")  @Log(operationType="add操作:",operationName="添加用戶")   public void testAOP(String userName,String password){        userService.addUser(userName, password);  }}

下面編寫測試類

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

spring,AOP,自定義注解,日志管理

數據庫數據:

spring,AOP,自定義注解,日志管理

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

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

以上這篇spring AOP自定義注解方式實現日志管理的實例講解就是小編分享給大家的全部內容了,希望能給大家一個參考,也希望大家多多支持VeVb武林網。


注:相關教程知識閱讀請移步到JAVA教程頻道。
發表評論 共有條評論
用戶名: 密碼:
驗證碼: 匿名發表
亚洲香蕉成人av网站在线观看_欧美精品成人91久久久久久久_久久久久久久久久久亚洲_热久久视久久精品18亚洲精品_国产精自产拍久久久久久_亚洲色图国产精品_91精品国产网站_中文字幕欧美日韩精品_国产精品久久久久久亚洲调教_国产精品久久一区_性夜试看影院91社区_97在线观看视频国产_68精品久久久久久欧美_欧美精品在线观看_国产精品一区二区久久精品_欧美老女人bb
久久人人97超碰精品888| 久久免费视频在线| 北条麻妃一区二区三区中文字幕| 亚洲精品免费网站| 亚洲精品98久久久久久中文字幕| 欧美激情喷水视频| 国产精品夫妻激情| 亚洲最大成人网色| 久久99久久99精品免观看粉嫩| 日韩精品极品在线观看播放免费视频| 午夜精品久久久久久久99黑人| 国产精品久久久久久av下载红粉| 亚洲国产欧美一区二区三区久久| 亚洲国产小视频在线观看| 中文字幕日韩在线视频| 亚洲无亚洲人成网站77777| 1769国产精品| 操91在线视频| 欧美最猛性xxxxx亚洲精品| 91久久在线视频| 日日摸夜夜添一区| 欧美日韩激情视频8区| 国产一区二区三区在线观看网站| 亚洲激情中文字幕| 久久精品人人做人人爽| 热门国产精品亚洲第一区在线| 91天堂在线观看| 欧美日韩精品二区| 色综合久久久888| 国产视频精品自拍| 日本精品一区二区三区在线播放视频| 亚洲男人av在线| 亚洲欧美中文日韩在线| 欧美日韩第一视频| 自拍偷拍亚洲在线| 日韩暖暖在线视频| 久久久爽爽爽美女图片| 欧美日韩成人在线观看| 91av在线网站| 亚洲欧洲在线视频| 国产极品精品在线观看| 亚洲精品国产精品自产a区红杏吧| 在线日韩第一页| 98视频在线噜噜噜国产| 97视频com| 欧美最近摘花xxxx摘花| 欧美日韩成人精品| 国产一区私人高清影院| 中文字幕精品网| 性色av一区二区三区在线观看| 亚洲国产成人精品一区二区| 久久国产精品久久久久久| 亚洲激情在线视频| 日韩成人免费视频| 国产精品久久久久久久久男| 久久影院资源站| 欧美高清性猛交| 91九色单男在线观看| 久久久久久久国产精品视频| 亚洲天堂av在线播放| 亚洲精品国产精品国自产观看浪潮| 国产精品午夜一区二区欲梦| 精品中文字幕在线2019| 久久影视三级福利片| 亚洲人成绝费网站色www| 亚洲精品国产拍免费91在线| 国产精品第七十二页| 国产精品久久久久久久久久99| 欧美一级bbbbb性bbbb喷潮片| 日本亚洲欧美三级| 国产日韩欧美91| 97在线视频国产| 国产精品一区二区三区毛片淫片| 在线观看精品国产视频| 亚洲美女喷白浆| 国产盗摄xxxx视频xxx69| 欧美日韩国产在线| 2023亚洲男人天堂| 亚洲精品影视在线观看| 国产小视频91| 国产网站欧美日韩免费精品在线观看| 在线观看久久av| 亚洲精品国产免费| 国产91在线播放精品91| 亚洲欧美成人一区二区在线电影| 日韩欧美a级成人黄色| 久久久久亚洲精品| 国产一区二区日韩精品欧美精品| 中文字幕日韩在线观看| 国产亚洲一区二区在线| 国产成人涩涩涩视频在线观看| 久久免费成人精品视频| 欧美激情va永久在线播放| 亚洲自拍小视频免费观看| 中文字幕亚洲天堂| 久久免费视频在线观看| 国产欧美婷婷中文| 91精品久久久久久久久久久久久| 亚洲乱码一区二区| 日韩在线视频观看正片免费网站| 国产精品白丝av嫩草影院| 中文字幕在线看视频国产欧美在线看完整| 国产噜噜噜噜噜久久久久久久久| 亚洲成人免费网站| 亚洲国产另类 国产精品国产免费| 国内精品模特av私拍在线观看| 日韩在线观看高清| 精品女厕一区二区三区| 日韩在线激情视频| 亚洲国产精品成人一区二区| 欧美日韩国产精品一区二区三区四区| 日韩网站在线观看| 久久久久北条麻妃免费看| 欧美国产欧美亚洲国产日韩mv天天看完整| 91国产高清在线| 久久久亚洲网站| 在线观看欧美视频| 国产精品国产福利国产秒拍| 亚洲天堂精品在线| 美女少妇精品视频| 国产成人拍精品视频午夜网站| 日本国产一区二区三区| 91在线免费视频| 在线视频欧美性高潮| 精品国产福利视频| 成人黄色大片在线免费观看| 欧美性在线观看| 成人精品一区二区三区电影黑人| 欧美人与性动交| 欧美国产日韩免费| 国产精品一香蕉国产线看观看| 久久久久久久久久av| 亚洲人成五月天| 亚洲黄色成人网| 日韩禁在线播放| 成人免费高清完整版在线观看| 热99精品里视频精品| 一本色道久久88综合亚洲精品ⅰ| 九九九久久久久久| 另类视频在线观看| 国产亚洲人成网站在线观看| 欧美一级在线亚洲天堂| 日韩av成人在线| 97人人模人人爽人人喊中文字| 亚洲精品国精品久久99热| 91精品视频在线看| 久久天天躁狠狠躁夜夜爽蜜月| 欧美资源在线观看| 欧美大片欧美激情性色a∨久久| 国产成人免费av电影| 国产日韩精品视频| 欧美裸体xxxxx| 久久99精品久久久久久噜噜| 久久香蕉频线观| 日韩高清a**址| 国产精品久久久久久久一区探花| 日韩中文娱乐网| 成人午夜在线视频一区| 国产精品第3页| 日韩黄色高清视频| 国产精品亚洲аv天堂网| 亚洲欧洲日产国产网站| 成人av资源在线播放| 国产精品色婷婷视频|