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

Spring?AOP利用切面實現(xiàn)日志保存的示例詳解

 更新時間:2022年11月17日 09:47:12   作者:陶陶吖  
最近領(lǐng)導(dǎo)讓寫個用切面實現(xiàn)日志保存,經(jīng)過調(diào)研和親測,以完美解決。在這里分享給大家,給有需要的碼友直接使用,希望對大家有所幫助

依賴引入

<dependency>
   <groupId>org.springframework.boot</groupId>
   <artifactId>spring-boot-starter-aop</artifactId>
</dependency>

創(chuàng)建表

DROP TABLE IF EXISTS `logger_record`;
CREATE TABLE `logger_record`  (
  `id` varchar(36) CHARACTER SET utf8 COLLATE utf8_general_ci NOT NULL COMMENT 'id',
  `description` varchar(255) CHARACTER SET utf8 COLLATE utf8_general_ci NULL DEFAULT NULL COMMENT '描述',
  `package_name` varchar(255) CHARACTER SET utf8 COLLATE utf8_general_ci NULL DEFAULT NULL COMMENT '操作所在的包',
  `class_name` varchar(255) CHARACTER SET utf8 COLLATE utf8_general_ci NULL DEFAULT NULL COMMENT '操作的類名',
  `method_name` varchar(255) CHARACTER SET utf8 COLLATE utf8_general_ci NULL DEFAULT NULL COMMENT '操作的方法名',
  `request_params` text CHARACTER SET utf8 COLLATE utf8_general_ci NULL COMMENT '操作方法的參數(shù)',
  `response_params` text CHARACTER SET utf8 COLLATE utf8_general_ci NULL COMMENT '操作方法的出參',
  `running_time` bigint NULL DEFAULT NULL COMMENT '運行時間',
  `created_by` varchar(32) CHARACTER SET utf8 COLLATE utf8_general_ci NULL DEFAULT NULL COMMENT '創(chuàng)建人ID',
  `date_created` datetime NULL DEFAULT CURRENT_TIMESTAMP COMMENT '創(chuàng)建時間',
  PRIMARY KEY (`id`) USING BTREE
) ENGINE = InnoDB CHARACTER SET = utf8 COLLATE = utf8_general_ci ROW_FORMAT = Dynamic;

SET FOREIGN_KEY_CHECKS = 1;

對象實體類

import com.baomidou.mybatisplus.annotation.IdType;
import com.baomidou.mybatisplus.annotation.TableId;
import com.baomidou.mybatisplus.annotation.TableName;
import com.fasterxml.jackson.annotation.JsonFormat;
import com.**.app.common.util.TimeUtils;
import lombok.Data;
import org.springframework.data.annotation.Id;

import java.io.Serializable;
import java.time.LocalDateTime;
import java.util.Date;

/**
 * Created by cb on 2022/11/15 10:07
 */
//@Entity
@Data
public class LoggerRecord implements Serializable {
    @Id
    @TableId(value = "id",type = IdType.ID_WORKER_STR)//可不引入注解,UUID生成
    private String id;
    /**
     * 操作方法的描述
     */
    private String description;//實際沒用上
    /**
     * 操作所在的包
     */
    private String packageName;
    /**
     * 操作的類名
     */
    private String className;
    /**
     * 操作的方法名
     */
    private String methodName;
    /**
     * 操作方法的參數(shù)
     */
    private String requestParams;
    /**
     * 操作方法的出參
     */
    private String responseParams;
    /**
     * 運行時間
     */
    private Long runningTime;
    /** 創(chuàng)建時間 */
    @JsonFormat(pattern = TimeUtils.PATTERN2)
    private LocalDateTime dateCreated;//可以用date

    /** 創(chuàng)建人ID */
    private String createdBy;//實際沒用上

}

注解方法

package com.**.app.server.annotation;

import java.lang.annotation.*;

/**
 * Created by cb on 2022/11/15 10:05
 * 日志描述的注解
 */
@Documented
@Retention(RetentionPolicy.RUNTIME)
@Target(ElementType.METHOD)
public @interface LoggerManager {
}

service方法

可根據(jù)自己項目去相應(yīng)改動

/**
 * 日志增刪改的接口
 * Created by cb on 2022/11/15 10:11
 */
@Service
public class LoggerRecordRepository extends ServiceImpl<LoggerRecordMapper, LoggerRecord> {
}

工具類

package com.**.app.server.util;

import org.apache.commons.lang.builder.ToStringBuilder;
import org.aspectj.lang.JoinPoint;
import org.aspectj.lang.reflect.MethodSignature;

import java.lang.reflect.Method;
import java.util.HashMap;
import java.util.Map;

/**
 * Created by cb on 2022/11/15 10:24
 */
public class AopUtil {
    /**
     * 獲取切點處的方法
     * @param joinPoint
     * @return
     */
    public static Method getMethod(JoinPoint joinPoint){
        MethodSignature signature = (MethodSignature) joinPoint.getSignature();
        Method method = signature.getMethod();
        return method;
    }

    /**
     //     * 將參數(shù)數(shù)組轉(zhuǎn)化為字符串
     //     * @param params  參數(shù)數(shù)組
     //     * @return 參數(shù)字符串
     //     */
    public static String getStringOfParams(Object[] params) {
        if (params.length <= 0 || params.length > 1024 || null == params) {
            return "";
        }

        StringBuffer paramString = new StringBuffer("參數(shù):   ");
        for (Object param : params) {
            //將參數(shù)轉(zhuǎn)換成字符串
            String s = ToStringBuilder.reflectionToString(param);
            paramString.append(s).append("||");
        }
        return paramString.toString();
    }

    /**
     * 轉(zhuǎn)換request 請求參數(shù)
     * @param paramMap request獲取的參數(shù)數(shù)組
     */
    public static Map<String, String> converMap(Map<String, String[]> paramMap) {
        Map<String, String> rtnMap = new HashMap<String, String>();
        for (String key : paramMap.keySet()) {
            rtnMap.put(key, paramMap.get(key)[0]);
        }
        return rtnMap;
    }

}

注解實現(xiàn)方法

package com.**.app.server.annotation;

import com.alibaba.fastjson.JSON;
import com.**.app.server.entity.log.LoggerRecord;
import com.**.app.server.service.LoggerRecordRepository;
import com.**.app.server.util.AopUtil;
import lombok.extern.slf4j.Slf4j;
import org.aspectj.lang.ProceedingJoinPoint;
import org.aspectj.lang.Signature;
import org.aspectj.lang.annotation.Around;
import org.aspectj.lang.annotation.Aspect;
import org.aspectj.lang.annotation.Pointcut;
import org.springframework.stereotype.Service;
import org.springframework.web.context.request.RequestAttributes;
import org.springframework.web.context.request.RequestContextHolder;

import javax.annotation.Resource;
import javax.servlet.http.HttpServletRequest;
import java.lang.reflect.Method;
import java.util.Map;

/**
 * Created by cb on 2022/11/15 10:19
 */
@Aspect
@Service
@Slf4j
public class LoggerAdvice {
    @Resource
    private LoggerRecordRepository loggerRecordRepository;
   


    /**
     * 切點,在注解處切入
     */
    @Pointcut("@annotation(com.safety.app.server.annotation.LoggerManager)")
    public void AroundPointCut(){
    }

    /**
     * 環(huán)繞通知 @Around  , 當(dāng)然也可以使用 @Before (前置通知)  @After (后置通知)
     * @param point
     * @return
     * @throws Throwable
     */
    @Around("AroundPointCut()")
    public Object around(ProceedingJoinPoint point) throws Throwable {

        long beginTime = System.currentTimeMillis();
        Object result = point.proceed();
        long time = System.currentTimeMillis() - beginTime;
        try {
            LoggerRecord loggerRecord = saveLog(point, time);
            loggerRecord.setResponseParams(JSON.toJSONString(result));
            loggerRecordRepository.save(loggerRecord);
        } catch (Exception e) {
        }finally {

            return result;
        }

    }


    /**
     * 保存日志
     * @param joinPoint
     * @param time
     */
    private LoggerRecord saveLog(ProceedingJoinPoint joinPoint, long time) {
        // 獲取RequestAttributes
        RequestAttributes requestAttributes = RequestContextHolder.getRequestAttributes();
        // 從獲取RequestAttributes中獲取HttpServletRequest的信息
        HttpServletRequest request = (HttpServletRequest) requestAttributes.resolveReference(RequestAttributes.REFERENCE_REQUEST);

        //獲取該切點處的方法
        Method method = AopUtil.getMethod(joinPoint);
        LoggerRecord loggerRecord = new LoggerRecord();
        //獲取切點處的注解
        LoggerManager loggerManager = method.getAnnotation(LoggerManager.class);
        if (null == loggerManager) {
            return loggerRecord;
        }
        //獲取請求的描述
//        String description = loggerManager.
        //獲取請求包名
        Signature signature = joinPoint.getSignature();
        //獲取請求的類名
        String className = joinPoint.getTarget().getClass().getName();
        //獲取請求的方法名
        String methodName = method.getName();
        //獲取請求的參數(shù)
        Map<String, String[]> parameterMap = request.getParameterMap();
        Map<String, String> stringStringMap = AopUtil.converMap(parameterMap);

        log.info("執(zhí)行===" + methodName + "===開始");
        //打印方法名
        log.info("方法名:" + signature.toString());
        //打印方法參數(shù)
        log.info("方法參數(shù):" + JSON.toJSONString(stringStringMap));
        log.info("執(zhí)行===" + methodName + "===結(jié)束");
        //將日志保存
//        loggerRecord.setDescription(description);
        loggerRecord.setPackageName(signature.toString());
        loggerRecord.setClassName(className);
        loggerRecord.setMethodName(methodName);
        loggerRecord.setRunningTime(time);
        loggerRecord.setRequestParams(JSON.toJSONString(stringStringMap));
        return loggerRecord;

    }
}

最后只需要在自己的接口上加注解@LoggerManager就可以實現(xiàn)此方法的入?yún)⒊鰠⑷罩颈4?/p>

/**
 * 測試
 */
@GetMapping("/test")
@ResponseBody
@LoggerManager
public ResponseResult test(@RequestParam("userName") String userName) throws BusinessException {
    Map<String, Object> verifyCodeMap = VerifyCodeUtils.verifyCode();
    redisUtils.set(VERIFY_CODE + userName, verifyCodeMap, 60);
    return new ResponseResult(verifyCodeMap);
}

保存數(shù)據(jù)庫后的圖片:

注:所有‘**’的地方為自己項目的包名。 好了,下期會改版此日志保存方法,在數(shù)據(jù)庫配置接口名稱 就可以實現(xiàn)日志的打印保存。

到此這篇關(guān)于Spring AOP利用切面實現(xiàn)日志保存的示例詳解的文章就介紹到這了,更多相關(guān)Spring AOP切面實現(xiàn)日志保存內(nèi)容請搜索腳本之家以前的文章或繼續(xù)瀏覽下面的相關(guān)文章希望大家以后多多支持腳本之家!

相關(guān)文章

  • Java并發(fā)之Phaser的全面解析詳解

    Java并發(fā)之Phaser的全面解析詳解

    Phaser是Java中一個靈活的同步工具,其優(yōu)點在于支持多階段的任務(wù)拆分與同步,并且能夠動態(tài)地注冊與注銷參與者,下面我們就來深入了解一下Phaser的應(yīng)用吧
    2024-02-02
  • Spring實現(xiàn)IoC和DI的方法詳解

    Spring實現(xiàn)IoC和DI的方法詳解

    IoC全稱Inversion of Control (控制反轉(zhuǎn)) ,這里的控制其實是控制權(quán)的意思,可以理解為對象的獲取權(quán)力和方式發(fā)生了發(fā)轉(zhuǎn),DI依賴注?是?個過程,是指IoC容器在創(chuàng)建Bean時, 去提供運?時所依賴的資源,?資源指的就是對象,本文介紹了Spring實現(xiàn)IoC和DI的方法
    2024-08-08
  • 新手小白入門必學(xué)JAVA面向?qū)ο笾鄳B(tài)

    新手小白入門必學(xué)JAVA面向?qū)ο笾鄳B(tài)

    說到多態(tài),一定離不開其它兩大特性:封裝和繼承,下面這篇文章主要給大家介紹了關(guān)于新手小白入門必學(xué)JAVA面向?qū)ο笾鄳B(tài)的相關(guān)資料,文中通過實例代碼介紹的非常詳細,需要的朋友可以參考下
    2022-02-02
  • Spring中Bean創(chuàng)建完后打印語句的兩種方法

    Spring中Bean創(chuàng)建完后打印語句的兩種方法

    這篇文章主要介紹了Spring中Bean創(chuàng)建完后打印語句的兩種方法,一個是實現(xiàn)InitializingBean接口,另一個使用@Bean注解和initMethod屬性,通過代碼示例介紹的非常詳細,感興趣的小伙伴可以參考閱讀
    2023-07-07
  • mybatis typeAliases 給實體類起別名的方法

    mybatis typeAliases 給實體類起別名的方法

    這篇文章主要介紹了mybatis typeAliases 給實體類起別名,本文給大家分享兩種用法,通過實例代碼給大家介紹的非常詳細,對大家的學(xué)習(xí)或工作具有一定的參考借鑒價值,需要的朋友可以參考下
    2020-09-09
  • 如何將eclipse項目導(dǎo)入到idea的方法步驟(圖文)

    如何將eclipse項目導(dǎo)入到idea的方法步驟(圖文)

    這篇文章主要介紹了如何將eclipse項目導(dǎo)入到idea的方法步驟,文中通過示例代碼介紹的非常詳細,對大家的學(xué)習(xí)或者工作具有一定的參考學(xué)習(xí)價值,需要的朋友們下面隨著小編來一起學(xué)習(xí)學(xué)習(xí)吧
    2020-03-03
  • mybatis中的多重if?條件判斷

    mybatis中的多重if?條件判斷

    這篇文章主要介紹了mybatis中的多重if?條件判斷,具有很好的參考價值,希望對大家有所幫助。如有錯誤或未考慮完全的地方,望不吝賜教
    2022-03-03
  • springboot+redis+lua實現(xiàn)分布式鎖的腳本

    springboot+redis+lua實現(xiàn)分布式鎖的腳本

    本文介紹了如何使用Spring Boot、Redis和Lua腳本實現(xiàn)分布式鎖,包括實現(xiàn)原理、代碼實現(xiàn)和存在的問題,感興趣的朋友跟隨小編一起看看吧
    2024-11-11
  • SpringBoot使用OpenCV示例總結(jié)

    SpringBoot使用OpenCV示例總結(jié)

    這篇文章主要介紹了SpringBoot使用OpenCV示例總結(jié),文中通過示例代碼介紹的非常詳細,對大家的學(xué)習(xí)或者工作具有一定的參考學(xué)習(xí)價值,需要的朋友們下面隨著小編來一起學(xué)習(xí)學(xué)習(xí)吧
    2020-08-08
  • SpringBoot集成POI導(dǎo)出Execl表格之統(tǒng)一工具類

    SpringBoot集成POI導(dǎo)出Execl表格之統(tǒng)一工具類

    這篇文章主要為大家詳細介紹了SpringBoot集成POI導(dǎo)出Execl表格之統(tǒng)一工具類,文中示例代碼介紹的非常詳細,具有一定的參考價值,感興趣的小伙伴們可以參考一下
    2022-09-09

最新評論

佳木斯市| 东明县| 鄱阳县| 十堰市| 休宁县| 那坡县| 海晏县| 枣阳市| 四会市| 稷山县| 方正县| 介休市| 延安市| 洛浦县| 泽州县| 宜良县| 潼关县| 夏邑县| 郎溪县| 柳林县| 资中县| 康平县| 南川市| 红桥区| 万山特区| 洪湖市| 伊通| 正安县| 广平县| 永康市| 泌阳县| 易门县| 麦盖提县| 平南县| 农安县| 随州市| 红河县| 关岭| 来凤县| 镇坪县| 泸水县|