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

自定義注解+AOP實(shí)現(xiàn)操作日志記錄方式

 更新時(shí)間:2026年01月14日 09:24:27   作者:小憨憨的牛  
文章介紹了如何使用AOP實(shí)現(xiàn)操作日志記錄,包括創(chuàng)建操作日志表和實(shí)體類、自定義注解、切面類以及測試

步驟:

  1. 引入AOP依賴
  2. 創(chuàng)建操作日志表和實(shí)體類
  3. 創(chuàng)建自定義注解(用于記錄哪些方法需要記錄日志)
  4. 創(chuàng)建切面,監(jiān)聽自定義的注解

一.Maven依賴

Swagger也是用來記錄日志的,可加可不加

        <!-- AOP -->
        <dependency>
            <groupId>org.springframework.boot</groupId>
            <artifactId>spring-boot-starter-aop</artifactId>
        </dependency>
        <!-- Swagger -->
        <dependency>
            <groupId>io.springfox</groupId>
            <artifactId>springfox-swagger2</artifactId>
            <version>2.7.0</version>
        </dependency>

        <dependency>
            <groupId>io.springfox</groupId>
            <artifactId>springfox-swagger-ui</artifactId>
            <version>2.7.0</version>
        </dependency>

二.創(chuàng)建日志記錄表和實(shí)體類

create_time和update_time字段在BaseEntity里面,且為自動(dòng)填充

package com.dhp.ets.entity;

import com.baomidou.mybatisplus.annotation.TableId;
import com.baomidou.mybatisplus.annotation.TableName;
import lombok.Data;

import java.util.Date;

/**
 * @Description
 * @Author dhp
 * @create 2025-05-12 10:29
 */
@Data
@TableName(value = "sys_action_log")
public class SysActionLogBean extends BaseEntity{

    @TableId
    private String id;
    /*
        操作人
        */
    private String userId ;
    /*
    操作人姓名
    */
    private String userName ;
    /*
    操作類型
    */
    private String actionType ;
    /*
    操作對象
    */
    private String actionClass ;
    /*
    操作方法
    */
    private String actionMethod ;
    /*
    操作參數(shù)
    */
    private String actionParams ;
    /*
    操作時(shí)間
    */
    private Date actionTime ;
    /*
    操作IP
    */
    private String actionIp ;
}

三.創(chuàng)建記錄日志自定義注解

該注解的value值用于記錄操作類型是什么,比如新增,修改,刪除.....

/**
 * 用于操作日志記錄
 */

@Target(ElementType.METHOD) //該注解用于方法上
@Retention(RetentionPolicy.RUNTIME) //運(yùn)行期間仍然有效,可以在運(yùn)行時(shí)通過反射獲取注解的屬性和值
public @interface SysLog {
    /**
     * 是否允許為空
     * @return
     */
    String value() default "";

}

四.創(chuàng)建切面類

controller類用Swagger的@Api注解記錄該控制層的所有方法是針對什么的,在方法上用@SysLog自定義注解用于記錄該方法具體做什么的,該切面類用于監(jiān)聽用了@SysLog注解的方法,獲取該方法和類的信息

該切面類沒有記錄人員信息,具體根據(jù)實(shí)際項(xiàng)目來寫入

package com.dhp.utils.syslog;

import com.alibaba.fastjson.JSON;
import com.alibaba.fastjson.JSONArray;
import com.alibaba.fastjson.JSONObject;
import com.dhp.ets.entity.SysActionLogBean;
import com.dhp.ets.service.SysActionLogService;
import org.aspectj.lang.JoinPoint;
import org.aspectj.lang.annotation.Aspect;
import org.aspectj.lang.annotation.Before;
import org.aspectj.lang.annotation.Pointcut;
import org.aspectj.lang.reflect.MethodSignature;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Component;
import org.springframework.web.context.request.RequestContextHolder;
import org.springframework.web.context.request.ServletRequestAttributes;

import javax.servlet.http.HttpServletRequest;
import java.lang.annotation.Annotation;
import java.lang.reflect.Method;
import java.net.InetAddress;
import java.net.UnknownHostException;
import java.util.Date;
import java.util.regex.Pattern;

/**
 * 系統(tǒng)日志:切面處理類
 */
@Aspect
@Component
public class SysLogAspect {

    private static Logger logger = LoggerFactory.getLogger(SysLogAspect.class);

    @Autowired
    private SysActionLogService sysActionLogService;

    //定義切點(diǎn) @Pointcut
    //在注解的位置切入代碼
    @Pointcut("@annotation(com.dhp.utils.syslog.SysLog)")
    public void logPoinCut() {
        logger.info("記錄操作日志");
    }

    //切面 配置通知
    //@AfterReturning("logPoinCut()")
    @Before("logPoinCut()")
    public void saveSysLog(JoinPoint joinPoint) {
        HttpServletRequest request = ((ServletRequestAttributes) RequestContextHolder.getRequestAttributes()).getRequest();
        //保存日志
        SysActionLogBean sysActionLog = new SysActionLogBean();

        //從切面織入點(diǎn)處通過反射機(jī)制獲取織入點(diǎn)處的方法
        MethodSignature signature = (MethodSignature) joinPoint.getSignature();
        //獲取切入點(diǎn)所在的方法
        Method method = signature.getMethod();

        //獲取操作
        SysLog sysLog = method.getAnnotation(SysLog.class);
        if (sysLog != null) {
            String value = sysLog.value();
            sysActionLog.setActionType(value);//保存獲取的操作
        }

        //獲取請求的類名
        String className = joinPoint.getTarget().getClass().getName();
        String  classChineseName = "";
        //獲取類的注解
        Annotation[]  annotations = joinPoint.getTarget().getClass().getAnnotations();
        for(Annotation annotation :annotations){
            if(annotation.annotationType().getName().indexOf("io.swagger.annotations.Api")>=0){
                //提取中文字符串
                  classChineseName =  getAnnotationDesc(annotation.toString());
            }
        }
        //獲取請求的方法名
        String methodName = method.getName();

        //處理請求的類名,只保留最后一段  并過濾掉操作日志本身
        String classSimpleName ;
        String[] classPaths = className.split("\\.");
        if(classPaths.length>0){
            classSimpleName = classPaths[classPaths.length-1];
        }else{
            classSimpleName = className;
        }

        //請求的參數(shù)
        Object[] args = joinPoint.getArgs();
        //將參數(shù)所在的數(shù)組轉(zhuǎn)換成json
        String params = JSON.toJSONString(args);

        //處理新增和修改參數(shù),過濾掉不重要的字段
        if (methodName.equals("save")) {
            JSONArray jsonArray = JSONArray.parseArray(params);
            JSONObject jsonObject = JSONObject.parseObject(jsonArray.get(0).toString());
            jsonObject.remove("createTime");
            jsonObject.remove("updateTime");
            if (jsonObject.containsKey("id")) {
                methodName = "update";
                sysActionLog.setActionType("修改");
            }
            params = jsonObject.toJSONString();
        }

        sysActionLog.setActionClass(classSimpleName);
        if(classChineseName!=null&&classChineseName.length()>0){
            sysActionLog.setActionClass(classChineseName);
        }

        sysActionLog.setActionMethod(methodName);
        sysActionLog.setActionParams(params);
        logger.info("操作參數(shù):{}",params);
        sysActionLog.setActionTime(new Date());
        //獲取用戶名
//        if(ShiroUtils.getUser()!=null) {
//            sysActionLog.setUserId(ShiroUtils.getUser().getId());
//            sysActionLog.setUserName(ShiroUtils.getUser().getUserName());
//        }
        sysActionLog.setActionIp(getIpAddress(request));

        //調(diào)用service保存SysLog實(shí)體類到數(shù)據(jù)庫
        sysActionLogService.saveOrUpdate(sysActionLog);
    }

    public final  String getIpAddress(HttpServletRequest request)  {
        String ipAddress = request.getHeader("x-forwarded-for");
        if (ipAddress == null || ipAddress.length() == 0 || "".equalsIgnoreCase(ipAddress)) {
            ipAddress = request.getRemoteAddr();
            if (ipAddress.equals("127.0.0.1") || ipAddress.equals("0:0:0:0:0:0:0:1")) {
                //根據(jù)網(wǎng)卡取本機(jī)配置的IP
                InetAddress inet = null;
                try {
                    inet = InetAddress.getLocalHost();
                } catch (UnknownHostException e) {
                    logger.error("獲取IP異常", e );
                }
                if(inet!=null){
                    ipAddress = inet.getHostAddress();
                }
            }
        }
        if (ipAddress != null && ipAddress.length() > 15 && ipAddress.indexOf(',') >= 0) { //"***.***.***.***".length() = 15
                ipAddress = ipAddress.substring(0,ipAddress.indexOf(','));
        }
        return ipAddress;
    }


//提取中文字符串
    public  String  getAnnotationDesc(String desc){
        String pattern = "[\\u4E00-\\u9FA5]+";
        StringBuilder  sb  = new StringBuilder();
        String[] splitStr = desc.split("");
        for(String str:splitStr) {
            if(Pattern.matches(pattern, str)){
                sb = sb.append(str) ;
            }
        }
        return sb.toString();
    }
}

五.測試

5.1controller類

@Api注解記錄該類的方法是人員管理的方法,@SysLog用于記錄保存操作

/**
 * @Author dhp
 * @create 2025-02-24 15:07
 */
@Api(description = "人員管理")
@RestController
@RequestMapping("/user")
public class UserController {

    @Autowired
    private UserService userService;

    @ApiOperation(value = "保存用戶")
    @PostMapping("save")
    @SysLog("保存")
    public WebResult save(@RequestBody User user){
        return userService.saveUsers(user);
    }
}

5.2 postman測試數(shù)據(jù)

人員表

操作日志記錄表:

總結(jié)

以上為個(gè)人經(jīng)驗(yàn),希望能給大家一個(gè)參考,也希望大家多多支持腳本之家。

相關(guān)文章

  • mybatis解析xml配置中${xxx}占位符的代碼邏輯

    mybatis解析xml配置中${xxx}占位符的代碼邏輯

    本文主要介紹了mybatis解析xml配置中${xxx}占位符的代碼邏輯,文中通過示例代碼介紹的非常詳細(xì),對大家的學(xué)習(xí)或者工作具有一定的參考學(xué)習(xí)價(jià)值,需要的朋友們下面隨著小編來一起學(xué)習(xí)學(xué)習(xí)吧<BR>
    2023-05-05
  • 淺談SpringBoot項(xiàng)目如何讓前端開發(fā)提高效率(小技巧)

    淺談SpringBoot項(xiàng)目如何讓前端開發(fā)提高效率(小技巧)

    這篇文章主要介紹了淺談SpringBoot項(xiàng)目如何讓前端開發(fā)提高效率(小技巧),主要介紹了Swagger和Nginx提高效率的方法,具有一定的參考價(jià)值,感興趣的小伙伴們可以參考一下
    2019-04-04
  • java中out.print和out.write的方法

    java中out.print和out.write的方法

    本文用一個(gè)小例子說明java out.print和out.write的方法,大家參考使用吧
    2013-11-11
  • java?ArrayList的深拷貝與淺拷貝問題

    java?ArrayList的深拷貝與淺拷貝問題

    這篇文章主要介紹了java?ArrayList的深拷貝與淺拷貝問題,具有很好的參考價(jià)值,希望對大家有所幫助。如有錯(cuò)誤或未考慮完全的地方,望不吝賜教
    2023-05-05
  • java 中使用maven shade plugin 打可執(zhí)行Jar包

    java 中使用maven shade plugin 打可執(zhí)行Jar包

    這篇文章主要介紹了java 中使用maven shade plugin 打可執(zhí)行Jar包的相關(guān)資料,需要的朋友可以參考下
    2017-05-05
  • Java?Timer使用講解

    Java?Timer使用講解

    Timer是一種工具,線程用其安排以后在后臺線程中執(zhí)行的任務(wù)。可安排任務(wù)執(zhí)行一次,或者定期重復(fù)執(zhí)行,這篇文章主要介紹了Java?Timer使用講解,需要的朋友可以參考下
    2022-11-11
  • 基于mybatis中<include>標(biāo)簽的作用說明

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

    這篇文章主要介紹了基于mybatis中<include>標(biāo)簽的作用說明,具有很好的參考價(jià)值,希望對大家有所幫助。一起跟隨小編過來看看吧
    2021-02-02
  • 詳解Java高階語法Volatile

    詳解Java高階語法Volatile

    這篇文章主要介紹了Java高階語法Volatile,文中通過示例代碼介紹的非常詳細(xì),對大家的學(xué)習(xí)或者工作具有一定的參考學(xué)習(xí)價(jià)值,需要的朋友們下面隨著小編來一起學(xué)習(xí)學(xué)習(xí)吧
    2019-03-03
  • Spring Boot 中PageHelper 插件使用配置思路詳解

    Spring Boot 中PageHelper 插件使用配置思路詳解

    這篇文章主要介紹了Spring Boot 中PageHelper 插件使用配置及實(shí)現(xiàn)思路,通過引入myabtis和pagehelper依賴,在yml中配置mybatis掃描和實(shí)體類,具體實(shí)現(xiàn)方法跟隨小編一起看看吧
    2021-08-08
  • SpringBoot?Cache?二級緩存的使用

    SpringBoot?Cache?二級緩存的使用

    本文主要介紹了SpringBoot?Cache?二級緩存的使用,文中通過示例代碼介紹的非常詳細(xì),對大家的學(xué)習(xí)或者工作具有一定的參考學(xué)習(xí)價(jià)值,需要的朋友們下面隨著小編來一起學(xué)習(xí)學(xué)習(xí)吧
    2023-06-06

最新評論

团风县| 葵青区| 邹平县| 清涧县| 霍州市| 洪洞县| 吴江市| 乐安县| 浠水县| 北海市| 巴东县| 卢氏县| 高唐县| 新密市| 衡东县| 淅川县| 屏南县| 淳安县| 闻喜县| 图木舒克市| 泰兴市| 乌拉特后旗| 广水市| 同江市| 历史| 临夏县| 井研县| 日照市| 榆树市| 天水市| 高州市| 和平区| 从化市| 苗栗县| 大姚县| 辽源市| 上思县| 宜兰县| 泸州市| 白城市| 济源市|