最新国产好看的视频,伊人天堂AV在线,国产Aaaaaa视频,蜜臀视频在线观看一区,人妻av色图,密臀久久久精品影片,青青视频免费观看毛片,久草在线观看视,国产三级精品色情在线

spring AOP自定義注解方式實(shí)現(xiàn)日志管理的實(shí)例講解

 更新時(shí)間:2018年01月22日 14:54:33   作者:悟空,你真了不得  
下面小編就為大家分享一篇spring AOP自定義注解方式實(shí)現(xiàn)日志管理的實(shí)例講解,具有很好的參考價(jià)值,希望對(duì)大家有所幫助。一起跟隨小編過來看看吧

今天繼續(xù)實(shí)現(xiàn)AOP,到這里我個(gè)人認(rèn)為是最靈活,可擴(kuò)展的方式了,就拿日志管理來說,用Spring AOP 自定義注解形式實(shí)現(xiàn)日志管理。廢話不多說,直接開始!?。?/p>

關(guān)于配置我還是的再說一遍。

在applicationContext-mvc.xml中要添加的

<mvc:annotation-driven />
<!-- 激活組件掃描功能,在包c(diǎn)om.gcx及其子包下面自動(dòng)掃描通過注解配置的組件 -->
<context:component-scan base-package="com.gcx" /> 
  
<!-- 啟動(dòng)對(duì)@AspectJ注解的支持 --> 
<!-- proxy-target-class等于true是強(qiáng)制使用cglib代理,proxy-target-class默認(rèn)是false,如果你的類實(shí)現(xiàn)了接口 就走JDK代理,如果沒有,走cglib代理 -->
<!-- 注:對(duì)于單利模式建議使用cglib代理,雖然JDK動(dòng)態(tài)代理比cglib代理速度快,但性能不如cglib -->
<!--如果不寫proxy-target-class="true"這句話也沒問題-->
<aop:aspectj-autoproxy proxy-target-class="true"/> 
<!--切面-->
<bean id="systemLogAspect" class="com.gcx.annotation.SystemLogAspect"></bean>

接下來開始編寫代碼。

創(chuàng)建日志類實(shí)體

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實(shí)現(xiàn)類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 {
  /** 要執(zhí)行的操作類型比如:add操作 **/ 
  public String operationType() default ""; 
   
  /** 要執(zhí)行的具體操作比如:添加用戶 **/ 
  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 創(chuàng)建時(shí)間:2015-10-19 下午4:29:05
 * @desc 切點(diǎn)類 
 */
@Aspect
@Component
public class SystemLogAspect {
  //注入Service用于把日志保存數(shù)據(jù)庫 
  @Resource //這里我用resource注解,一般用的是@Autowired,他們的區(qū)別如有時(shí)間我會(huì)在后面的博客中來寫
  private SystemLogService systemLogService; 
  
  private static final Logger logger = LoggerFactory.getLogger(SystemLogAspect. class); 
  
  //Controller層切點(diǎn) 
  @Pointcut("execution (* com.gcx.controller..*.*(..))") 
  public void controllerAspect() { 
  } 
  
  /** 
   * 前置通知 用于攔截Controller層記錄用戶的操作 
   * 
   * @param joinPoint 切點(diǎn) 
   */ 
  @Before("controllerAspect()")
  public void doBefore(JoinPoint joinPoint) {
    System.out.println("==========執(zhí)行controller前置通知===============");
    if(logger.isInfoEnabled()){
      logger.info("before " + joinPoint);
    }
  }  
  
  //配置controller環(huán)繞通知,使用在方法aspect()上注冊(cè)的切入點(diǎn)
   @Around("controllerAspect()")
   public void around(JoinPoint joinPoint){
     System.out.println("==========開始執(zhí)行controller環(huán)繞通知===============");
     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("==========結(jié)束執(zhí)行controller環(huán)繞通知===============");
     } 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 切點(diǎn) 
   */ 
  @After("controllerAspect()") 
  public void after(JoinPoint joinPoint) { 
 
    /* HttpServletRequest request = ((ServletRequestAttributes) RequestContextHolder.getRequestAttributes()).getRequest(); 
    HttpSession session = request.getSession(); */
    //讀取session中的用戶 
    // User user = (User) session.getAttribute("user"); 
    //請(qǐng)求的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; 
          } 
        } 
      }
      //*========控制臺(tái)輸出=========*// 
      System.out.println("=====controller后置通知開始====="); 
      System.out.println("請(qǐng)求方法:" + (joinPoint.getTarget().getClass().getName() + "." + joinPoint.getSignature().getName() + "()")+"."+operationType); 
      System.out.println("方法描述:" + operationName); 
      System.out.println("請(qǐng)求人:" + user.getName()); 
      System.out.println("請(qǐng)求IP:" + ip); 
      //*========數(shù)據(jù)庫日志=========*// 
      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()); 
      //保存數(shù)據(jù)庫 
      systemLogService.insert(log); 
      System.out.println("=====controller后置通知結(jié)束====="); 
    } catch (Exception e) { 
      //記錄本地異常日志 
      logger.error("==后置通知異常=="); 
      logger.error("異常信息:{}", e.getMessage()); 
    } 
  } 
  
  //配置后置返回通知,使用在方法aspect()上注冊(cè)的切入點(diǎn)
   @AfterReturning("controllerAspect()")
   public void afterReturn(JoinPoint joinPoint){
     System.out.println("=====執(zhí)行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); 
    //獲取請(qǐng)求ip 
    String ip = request.getRemoteAddr(); */ 
    //獲取用戶請(qǐng)求方法的參數(shù)并序列化為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; 
           } 
         } 
       }
       /*========控制臺(tái)輸出=========*/ 
      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("請(qǐng)求人:" + user.getName()); 
      System.out.println("請(qǐng)求IP:" + ip); 
      System.out.println("請(qǐng)求參數(shù):" + params); 
        /*==========數(shù)據(jù)庫日志=========*/ 
      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); 
      //保存數(shù)據(jù)庫 
      systemLogService.insert(log); 
      System.out.println("=====異常通知結(jié)束====="); 
    } catch (Exception ex) { 
      //記錄本地異常日志 
      logger.error("==異常通知異常=="); 
      logger.error("異常信息:{}", ex.getMessage()); 
    } 
     /*==========記錄本地異常日志==========*/ 
    logger.error("異常方法:{}異常代碼:{}異常信息:{}參數(shù):{}", joinPoint.getTarget().getClass().getName() + joinPoint.getSignature().getName(), e.getClass().getName(), e.getMessage(), params); 
 
  } 
  
}

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

下面開始在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(){
    //啟動(dòng)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");
  }

數(shù)據(jù)庫數(shù)據(jù):

我原本想寫兩個(gè)切點(diǎn),一個(gè)是service層,一個(gè)是controller層,service層是用來記錄異常信息的日志,而controller層的是用來記錄功能的日志,運(yùn)行結(jié)果如下。

這樣做的話不知道在實(shí)際的項(xiàng)目中運(yùn)行效率好不好,在這里請(qǐng)看到博客的大牛給點(diǎn)建議?。?/p>

以上這篇spring AOP自定義注解方式實(shí)現(xiàn)日志管理的實(shí)例講解就是小編分享給大家的全部內(nèi)容了,希望能給大家一個(gè)參考,也希望大家多多支持腳本之家。

相關(guān)文章

  • 解決報(bào)錯(cuò):java:讀取jar包時(shí)出錯(cuò):error in opening zip file問題

    解決報(bào)錯(cuò):java:讀取jar包時(shí)出錯(cuò):error in opening zip 

    文章總結(jié):解決Java讀取jar包時(shí)出錯(cuò)的問題,通過下載源碼并刷新項(xiàng)目解決了問題,希望對(duì)大家有所幫助
    2024-11-11
  • Java compareTo用法詳解

    Java compareTo用法詳解

    在Java編程中,有時(shí)候我們需要對(duì)對(duì)象進(jìn)行比較和排序,為了實(shí)現(xiàn)這一目標(biāo),Java提供了一個(gè)非常有用的接口叫做Comparable,以及一個(gè)重要的方法compareTo,下面我們就來看看compareTo的具體用法吧
    2023-09-09
  • IDEA配置Maven的超詳細(xì)步驟

    IDEA配置Maven的超詳細(xì)步驟

    Maven是一個(gè)能使我們的java程序開發(fā)節(jié)省時(shí)間和精力,是開發(fā)變得相對(duì)簡單,還能使開發(fā)規(guī)范化的工具,下面這篇文章主要給大家介紹了關(guān)于IDEA配置Maven的超詳細(xì)步驟,文中通過圖文介紹的非常詳細(xì),需要的朋友可以參考下
    2022-08-08
  • Java正則表達(dá)式_動(dòng)力節(jié)點(diǎn)Java學(xué)院整理

    Java正則表達(dá)式_動(dòng)力節(jié)點(diǎn)Java學(xué)院整理

    什么是正則表達(dá)式,正則表達(dá)式的作用是什么?這篇文章主要為大家詳細(xì)介紹了Java正則表達(dá)式的相關(guān)資料,具有一定的參考價(jià)值,感興趣的小伙伴們可以參考一下
    2017-05-05
  • Springboot集成mqtt客戶端詳解

    Springboot集成mqtt客戶端詳解

    MQTT是一個(gè)基于客戶端-服務(wù)器的消息發(fā)布/訂閱傳輸協(xié)議。MQTT協(xié)議是輕量、簡單、開放和易于實(shí)現(xiàn)的,這些特點(diǎn)使它適用范圍非常廣泛。本文為大家分享了Springboot整合mqtt服務(wù)的示例代碼,需要的可以參考一下
    2022-10-10
  • 解讀Spring事務(wù)是如何實(shí)現(xiàn)的

    解讀Spring事務(wù)是如何實(shí)現(xiàn)的

    這篇文章主要介紹了Spring事務(wù)是如何實(shí)現(xiàn)的問題,具有很好的參考價(jià)值,希望對(duì)大家有所幫助。如有錯(cuò)誤或未考慮完全的地方,望不吝賜教
    2023-03-03
  • SpringBoot搭建多數(shù)據(jù)源的實(shí)現(xiàn)方法

    SpringBoot搭建多數(shù)據(jù)源的實(shí)現(xiàn)方法

    說起多數(shù)據(jù)源,一般都來解決那些問題呢,主從模式或者業(yè)務(wù)比較復(fù)雜需要連接不同的分庫來支持業(yè)務(wù)。本文主要介紹了SpringBoot搭建多數(shù)據(jù)源的實(shí)現(xiàn)方法,感興趣的可以了解一下,感興趣的可以額了解一下
    2021-12-12
  • SpringBoot升級(jí)指定jackson版本的問題

    SpringBoot升級(jí)指定jackson版本的問題

    這篇文章主要介紹了SpringBoot升級(jí)指定jackson版本,本文給大家分享了漏洞通告及修改Springboot中jackson版本的問題,需要的朋友可以參考下
    2022-08-08
  • idea設(shè)置在包里面在創(chuàng)建一個(gè)包方式

    idea設(shè)置在包里面在創(chuàng)建一個(gè)包方式

    這篇文章主要介紹了idea設(shè)置在包里面在創(chuàng)建一個(gè)包方式,具有很好的參考價(jià)值,希望對(duì)大家有所幫助,如有錯(cuò)誤或未考慮完全的地方,望不吝賜教
    2024-05-05
  • 詳解IntelliJ IDEA 快捷鍵整合(大全)

    詳解IntelliJ IDEA 快捷鍵整合(大全)

    這篇文章主要介紹了詳解IntelliJ IDEA 快捷鍵整合,小編覺得挺不錯(cuò)的,現(xiàn)在分享給大家,也給大家做個(gè)參考。一起跟隨小編過來看看吧
    2019-08-08

最新評(píng)論

武宁县| 库伦旗| 苏尼特右旗| 呈贡县| 延庆县| 沁源县| 鄢陵县| 黎平县| 赞皇县| 鲁山县| 上蔡县| 仁布县| 包头市| 连城县| 保靖县| 胶南市| 清徐县| 敦化市| 玉环县| 公主岭市| 博野县| 朝阳区| 和硕县| 和政县| 庄浪县| 长寿区| 资源县| 徐汇区| 梁河县| 麻城市| 昌邑市| 平遥县| 拉孜县| 长葛市| 西乡县| 巢湖市| 福泉市| 梁河县| 祁连县| 桃园市| 肃南|