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

springboot自定義日志注解的實(shí)現(xiàn)

 更新時(shí)間:2022年03月07日 15:50:46   作者:江流。  
本文主要介紹了springboot自定義日志注解的實(shí)現(xiàn),文中通過(guò)示例代碼介紹的非常詳細(xì),具有一定的參考價(jià)值,感興趣的小伙伴們可以參考一下

前言

      在之前的日志記錄的寫法中,我們大多是寫一個(gè)工具類,在這個(gè)類里面定義日志保存的方法,然后再controller中執(zhí)行請(qǐng)求的時(shí)候調(diào)用即可,雖然調(diào)用僅僅一行代碼,但是不夠友好;所有可以寫一個(gè)類似于@Controller等的注解,在需要保存日志的方法上面加上一個(gè)注解,這樣不用在每個(gè)都寫一端代碼;話不多說(shuō)上代碼

     1、首先一個(gè)log的實(shí)體類,這個(gè)無(wú)關(guān)緊要    

package com.sysmg.system.domain;
?
import java.io.Serializable;
import java.util.Date;
?
import javax.persistence.Column;
import javax.persistence.GeneratedValue;
import javax.persistence.Id;
import javax.persistence.Table;
import javax.persistence.Transient;
?
import com.sysmg.common.annotation.ExportConfig;
?
@Table(name = "t_log")
public class SysLog implements Serializable {
?
?? ?private static final long serialVersionUID = -8878596941954995444L;
?
?? ?@Id
?? ?@GeneratedValue(generator = "JDBC")
?? ?@Column(name = "ID")
?? ?private Long id;
?
?? ?@Column(name = "USERNAME")
?? ?@ExportConfig(value = "操作用戶")
?? ?private String username;
?
?? ?@Column(name = "OPERATION")
?? ?@ExportConfig(value = "描述")
?? ?private String operation;
?
?? ?@Column(name = "TIME")
?? ?@ExportConfig(value = "耗時(shí)(毫秒)")
?? ?private Long time;
?
?? ?@Column(name = "METHOD")
?? ?@ExportConfig(value = "操作方法")
?? ?private String method;
?
?? ?@Column(name = "PARAMS")
?? ?@ExportConfig(value = "參數(shù)")
?? ?private String params;
?
?? ?@Column(name = "IP")
?? ?@ExportConfig(value = "IP地址")
?? ?private String ip;
?
?? ?@Column(name = "CREATE_TIME")
?? ?@ExportConfig(value = "操作時(shí)間", convert = "c:com.sysmg.common.util.poi.convert.TimeConvert")
?? ?private Date createTime;
?
?? ?@Column(name = "LOCATION")
?? ?@ExportConfig(value = "地點(diǎn)")
?? ?private String location;
?? ?
?? ?// 用于搜索條件中的時(shí)間字段
?? ?@Transient
?? ?private String timeField;
?
?? ?/**
?? ? * @return ID
?? ? */
?? ?public Long getId() {
?? ??? ?return id;
?? ?}
?
?? ?/**
?? ? * @param id
?? ? */
?? ?public void setId(Long id) {
?? ??? ?this.id = id;
?? ?}
?
?? ?/**
?? ? * @return USERNAME
?? ? */
?? ?public String getUsername() {
?? ??? ?return username;
?? ?}
?
?? ?/**
?? ? * @param username
?? ? */
?? ?public void setUsername(String username) {
?? ??? ?this.username = username == null ? null : username.trim();
?? ?}
?
?? ?/**
?? ? * @return OPERATION
?? ? */
?? ?public String getOperation() {
?? ??? ?return operation;
?? ?}
?
?? ?/**
?? ? * @param operation
?? ? */
?? ?public void setOperation(String operation) {
?? ??? ?this.operation = operation == null ? null : operation.trim();
?? ?}
?
?? ?/**
?? ? * @return TIME
?? ? */
?? ?public Long getTime() {
?? ??? ?return time;
?? ?}
?
?? ?/**
?? ? * @param time
?? ? */
?? ?public void setTime(Long time) {
?? ??? ?this.time = time;
?? ?}
?
?? ?/**
?? ? * @return METHOD
?? ? */
?? ?public String getMethod() {
?? ??? ?return method;
?? ?}
?
?? ?/**
?? ? * @param method
?? ? */
?? ?public void setMethod(String method) {
?? ??? ?this.method = method == null ? null : method.trim();
?? ?}
?
?? ?/**
?? ? * @return PARAMS
?? ? */
?? ?public String getParams() {
?? ??? ?return params;
?? ?}
?
?? ?/**
?? ? * @param params
?? ? */
?? ?public void setParams(String params) {
?? ??? ?this.params = params == null ? null : params.trim();
?? ?}
?
?? ?/**
?? ? * @return IP
?? ? */
?? ?public String getIp() {
?? ??? ?return ip;
?? ?}
?
?? ?/**
?? ? * @param ip
?? ? */
?? ?public void setIp(String ip) {
?? ??? ?this.ip = ip == null ? null : ip.trim();
?? ?}
?
?? ?/**
?? ? * @return CREATE_TIME
?? ? */
?? ?public Date getCreateTime() {
?? ??? ?return createTime;
?? ?}
?
?? ?/**
?? ? * @param createTime
?? ? */
?? ?public void setCreateTime(Date createTime) {
?? ??? ?this.createTime = createTime;
?? ?}
?
?? ?public String getLocation() {
?? ??? ?return location;
?? ?}
?
?? ?public void setLocation(String location) {
?? ??? ?this.location = location;
?? ?}
?
?? ?public String getTimeField() {
?? ??? ?return timeField;
?? ?}
?
?? ?public void setTimeField(String timeField) {
?? ??? ?this.timeField = timeField;
?? ?}
?? ?
?
}

  2、定義一個(gè)注解接口

package com.sysmg.common.annotation;
?
import java.lang.annotation.ElementType;
import java.lang.annotation.Retention;
import java.lang.annotation.RetentionPolicy;
import java.lang.annotation.Target;
?
@Target(ElementType.METHOD)
@Retention(RetentionPolicy.RUNTIME)
public @interface Log {
? ? String value() default "";
}

@Target(ElementType.METHOD)代表是方法上的注解,當(dāng)然也可以是類注解,字段注解等

@Target(ElementType.TYPE) //接口、類、枚舉、注解 
@Target(ElementType.FIELD) //字段、枚舉的常量 
@Target(ElementType.METHOD) //方法 
@Target(ElementType.PARAMETER) //方法參數(shù) 
@Target(ElementType.CONSTRUCTOR) //構(gòu)造函數(shù) 
@Target(ElementType.LOCAL_VARIABLE)//局部變量 
@Target(ElementType.ANNOTATION_TYPE)//注解 
@Target(ElementType.PACKAGE) ///包 

@Retention(RetentionPolicy.RUNTIME)代表注解會(huì)被jvm保留,這個(gè)參數(shù)有三種

RetentionPolicy.SOURCE —— 這種類型的Annotations只在源代碼級(jí)別保留,編譯時(shí)就會(huì)被忽略 
RetentionPolicy.CLASS —— 這種類型的Annotations編譯時(shí)被保留,在class文件中存在,但JVM將會(huì)忽略 
RetentionPolicy.RUNTIME —— 這種類型的Annotations將被JVM保留,所以他們能在運(yùn)行時(shí)被JVM或其他使用反射機(jī)制的代碼所讀取和使用。
一般默認(rèn)第三種

當(dāng)然也可以寫

@Documented和@Order(優(yōu)先級(jí)  數(shù)字越小優(yōu)先級(jí)越高)

@Documented 注解表明這個(gè)注解應(yīng)該被 javadoc工具記錄. 默認(rèn)情況下,javadoc是不包括注解的. 但如果聲明注解時(shí)指定了 @Documented,則它會(huì)被 javadoc 之類的工具處理, 所以注解類型信息也會(huì)被包括在生成的文檔中。

@Order標(biāo)記定義了組件的加載順序,這個(gè)標(biāo)記包含一個(gè)value屬性。屬性接受整形值。如:1,2 等等。值越小擁有越高的優(yōu)先級(jí)。Ordered.HIGHEST_PRECEDENCE這個(gè)屬性值是最高優(yōu)先級(jí)的屬性,它的值是-2147483648,對(duì)應(yīng)的最低屬性值是Ordered.LOWEST_PRECEDENCE,它的值是2147483647。

String value() default ""

這個(gè)代表是要傳遞的參數(shù),類似

@Autowired(required=true)
?
?
public @interface Autowired {
?
?? ?/**
?? ? * Declares whether the annotated dependency is required.
?? ? * <p>Defaults to {@code true}.
?? ? */
?? ?boolean required() default true;
?
}

springmvc項(xiàng)目還需要開啟切面編程

<aop:aspectj-autoproxy proxy-target-class="true"/>

springboot默認(rèn)是開啟的

3、定義注解的實(shí)現(xiàn)類,也就是這個(gè)注解要做什么事

package com.sysmg.common.aspect;
?
import java.lang.reflect.Method;
import java.util.Date;
?
import javax.servlet.http.HttpServletRequest;
?
import org.apache.shiro.SecurityUtils;
import org.aspectj.lang.ProceedingJoinPoint;
import org.aspectj.lang.annotation.Around;
import org.aspectj.lang.annotation.Aspect;
import org.aspectj.lang.annotation.Pointcut;
import org.aspectj.lang.reflect.MethodSignature;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.core.LocalVariableTableParameterNameDiscoverer;
import org.springframework.stereotype.Component;
?
import com.fasterxml.jackson.databind.ObjectMapper;
import com.sysmg.common.annotation.Log;
import com.sysmg.common.util.AddressUtilsBak;
import com.sysmg.common.util.HttpContextUtils;
import com.sysmg.common.util.IPUtils;
import com.sysmg.system.domain.SysLog;
import com.sysmg.system.domain.User;
import com.sysmg.system.service.LogService;
?
@Aspect
@Component
public class LogAspect {
?
?? ?@Autowired
?? ?private LogService logService;
?
?? ?@Autowired
?? ?ObjectMapper mapper;
?
?? ?@Pointcut("@annotation(com.sysmg.common.annotation.Log)")
?? ?public void pointcut() {
?? ?}
?
?? ?@Around("pointcut()")
?? ?public Object around(ProceedingJoinPoint point) {
?? ??? ?Object result = null;
?? ??? ?long beginTime = System.currentTimeMillis();
?? ??? ?try {
?? ??? ??? ?result = point.proceed();
?? ??? ?} catch (Throwable e) {
?? ??? ??? ?e.printStackTrace();
?? ??? ?}
?? ??? ?long time = System.currentTimeMillis() - beginTime;
?? ??? ?saveLog(point, time);
?? ??? ?return result;
?? ?}
?
?? ?private void saveLog(ProceedingJoinPoint joinPoint, long time) {
?? ??? ?User user = (User) SecurityUtils.getSubject().getPrincipal();
?? ??? ?MethodSignature signature = (MethodSignature) joinPoint.getSignature();
?? ??? ?Method method = signature.getMethod();
?? ??? ?SysLog log = new SysLog();
?? ??? ?Log logAnnotation = method.getAnnotation(Log.class);
?? ??? ?if (logAnnotation != null) {
?? ??? ??? ?log.setOperation(logAnnotation.value());
?? ??? ?}
?? ??? ?String className = joinPoint.getTarget().getClass().getName();
?? ??? ?String methodName = signature.getName();
?? ??? ?log.setMethod(className + "." + methodName + "()");
?? ??? ?Object[] args = joinPoint.getArgs();
?? ??? ?LocalVariableTableParameterNameDiscoverer u = new LocalVariableTableParameterNameDiscoverer();
?? ??? ?String[] paramNames = u.getParameterNames(method);
?? ??? ?if (args != null && paramNames != null) {
?? ??? ??? ?String params = "";
?? ??? ??? ?for (int i = 0; i < args.length; i++) {
?? ??? ??? ??? ?params += " ?" + paramNames[i] + ": " + args[i];
?? ??? ??? ?}
?? ??? ??? ?log.setParams(params);
?? ??? ?}
?? ??? ?HttpServletRequest request = HttpContextUtils.getHttpServletRequest();
?? ??? ?log.setIp(IPUtils.getIpAddr(request));
?? ??? ?log.setUsername(user.getUsername());
?? ??? ?log.setTime(time);
?? ??? ?log.setCreateTime(new Date());
?? ??? ?log.setLocation(AddressUtilsBak.getRealAddressByIP(log.getIp(), mapper));
?? ??? ?this.logService.save(log);
?? ?}
}

這里的實(shí)現(xiàn)類中日志添加的方法中使用的淘寶的獲取ip服務(wù),后續(xù)會(huì)加上去,其實(shí)這里面可以隨便寫一個(gè)實(shí)現(xiàn)方法,因?yàn)槲沂橇艄ぞ邆浞?,所以記錄的較多

具體的@Aspect、@Pointcut、@Around、@Before、@After等aop相關(guān)的注解和參數(shù)需要自己去鞏固一下知識(shí)

4、然后就可以在你想要記錄日志的地方使用即可

package com.sysmg.controller;
?
import java.util.List;
import java.util.Map;
?
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Controller;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.ResponseBody;
?
import com.github.pagehelper.PageHelper;
import com.github.pagehelper.PageInfo;
import com.sysmg.common.annotation.Log;
import com.sysmg.common.domain.QueryRequest;
import com.sysmg.common.domain.ResponseBo;
import com.sysmg.common.util.FileUtils;
?
@Controller
public class TestController{
?
?? ?@Log("規(guī)則")
?? ?@RequestMapping("test")
?? ?public String index() {
?? ??? ?return "test";
?? ?}
}?? ?

大概這樣就可以使用了,目前里面缺少aop相關(guān)知識(shí)的介紹以及獲取訪問(wèn)ip的工具類,不過(guò)跟本課題關(guān)系不大,后續(xù)會(huì)更上去

到此這篇關(guān)于springboot自定義日志注解的實(shí)現(xiàn)的文章就介紹到這了,更多相關(guān)springboot自定義日志注解內(nèi)容請(qǐng)搜索腳本之家以前的文章或繼續(xù)瀏覽下面的相關(guān)文章希望大家以后多多支持腳本之家!

相關(guān)文章

  • Java多線程間的5種通信方式小結(jié)

    Java多線程間的5種通信方式小結(jié)

    有兩個(gè)線程,A 線程向一個(gè)集合里面依次添加元素“abc”字符串,一共添加十次,當(dāng)添加到第五次的時(shí)候,希望 B 線程能夠收到 A 線程的通知,然后 B 線程執(zhí)行相關(guān)的業(yè)務(wù)操作,本文介紹的5種通信方式都是基本這兩種模型來(lái)實(shí)現(xiàn)的,需要的朋友可以參考下
    2023-10-10
  • Java之JFrame輸出Helloworld實(shí)例

    Java之JFrame輸出Helloworld實(shí)例

    這篇文章主要介紹了Java之JFrame輸出Helloworld的方法,以輸出Helloworld的實(shí)例分析了JFrame的簡(jiǎn)單入門技巧,需要的朋友可以參考下
    2015-02-02
  • 如何理解Java線程池及其使用方法

    如何理解Java線程池及其使用方法

    線程池是首先創(chuàng)建一些線程,它們的集合稱為線程池。使用線程池可以提高性能,它在系統(tǒng)啟動(dòng)時(shí)創(chuàng)建大量空閑的線程,程序?qū)⒁粋€(gè)任務(wù)傳給線程池,它就會(huì)啟動(dòng)一條線程來(lái)執(zhí)行這個(gè)任務(wù),執(zhí)行結(jié)束以后,該線程并不會(huì)死亡,而是再次返回線程池中成為空閑狀態(tài),等待執(zhí)行下一個(gè)任務(wù)
    2021-06-06
  • Java 字符串截取及常見場(chǎng)景與方法詳解

    Java 字符串截取及常見場(chǎng)景與方法詳解

    在 Java 開發(fā)中,截取字符串是一個(gè)非常常見的操作,無(wú)論是獲取文件名還是提取某些特定內(nèi)容,本文詳細(xì)介紹了截取字符串最后一位及其他常見截取操作的多種方法,幫助開發(fā)者快速上手,感興趣的朋友跟隨小編一起看看吧
    2024-12-12
  • Spring的定時(shí)任務(wù)@Scheduled源碼詳解

    Spring的定時(shí)任務(wù)@Scheduled源碼詳解

    這篇文章主要介紹了Spring的定時(shí)任務(wù)@Scheduled源碼詳解,@Scheduled注解是包org.springframework.scheduling.annotation中的一個(gè)注解,主要是用來(lái)開啟定時(shí)任務(wù),本文提供了部分實(shí)現(xiàn)代碼與思路,需要的朋友可以參考下
    2023-09-09
  • 關(guān)于Java中Bean的生命周期詳解

    關(guān)于Java中Bean的生命周期詳解

    這篇文章主要介紹了關(guān)于Java中Bean的生命周期詳解,所謂的?命周期指的是?個(gè)對(duì)象從誕?到銷毀的整個(gè)?命過(guò)程,我們把這個(gè)過(guò)程就叫做?個(gè)對(duì)象的?命周期,需要的朋友可以參考下
    2023-08-08
  • 詳解如何在SpringBoot中優(yōu)雅地重試調(diào)用第三方API

    詳解如何在SpringBoot中優(yōu)雅地重試調(diào)用第三方API

    在實(shí)際的應(yīng)用中,我們經(jīng)常需要調(diào)用第三方API來(lái)獲取數(shù)據(jù)或執(zhí)行某些操作,文中的示例代碼講解詳細(xì),感興趣的小伙伴可以跟隨小編一起學(xué)習(xí)一下
    2023-12-12
  • 基于mybatis中<include>標(biāo)簽的作用說(shuō)明

    基于mybatis中<include>標(biāo)簽的作用說(shuō)明

    這篇文章主要介紹了基于mybatis中<include>標(biāo)簽的作用說(shuō)明,具有很好的參考價(jià)值,希望對(duì)大家有所幫助。一起跟隨小編過(guò)來(lái)看看吧
    2021-02-02
  • Java使用JDBC驅(qū)動(dòng)連接MySQL數(shù)據(jù)庫(kù)

    Java使用JDBC驅(qū)動(dòng)連接MySQL數(shù)據(jù)庫(kù)

    這篇文章主要為大家詳細(xì)介紹了Java使用JDBC驅(qū)動(dòng)連接MySQL數(shù)據(jù)庫(kù)的具體步驟,具有一定的參考價(jià)值,感興趣的小伙伴們可以參考一下
    2016-12-12
  • Java通過(guò)XPath獲取XML文件中符合特定條件的節(jié)點(diǎn)

    Java通過(guò)XPath獲取XML文件中符合特定條件的節(jié)點(diǎn)

    今天小編就為大家分享一篇關(guān)于Java通過(guò)XPath獲取XML文件中符合特定條件的節(jié)點(diǎn),小編覺得內(nèi)容挺不錯(cuò)的,現(xiàn)在分享給大家,具有很好的參考價(jià)值,需要的朋友一起跟隨小編來(lái)看看吧
    2019-01-01

最新評(píng)論

唐山市| 论坛| 宝应县| 岳池县| 泰安市| 舟曲县| 通海县| 吉木萨尔县| 安义县| 师宗县| 平顺县| 阿克苏市| 青岛市| 神农架林区| 伊川县| 昌乐县| 广元市| 平陆县| 本溪市| 内江市| 松滋市| 蒲城县| 广宁县| 黄骅市| 长寿区| 英山县| 吴旗县| 阿拉善盟| 图们市| 葫芦岛市| 乐至县| 鹤峰县| 隆子县| 通榆县| 张家界市| 儋州市| 安平县| 胶南市| 远安县| 平果县| 恭城|