欧美bbbwbbbw肥妇,免费乱码人妻系列日韩,一级黄片

運(yùn)用Spring?Aop+注解實(shí)現(xiàn)日志記錄

 更新時(shí)間:2022年01月29日 08:46:26   作者:Alickx  
我們都知道Spring框架的兩大特性分別是 IOC (控制反轉(zhuǎn))和 AOP (面向切面),這個(gè)是每一個(gè)Spring學(xué)習(xí)視頻里面一開(kāi)始都會(huì)提到的,這里,如果我們使用Aop來(lái)記錄日志,那是再好不過(guò)了,感興趣的朋友跟隨小編一起學(xué)習(xí)下Spring?Aop注解實(shí)現(xiàn)日志記錄的過(guò)程吧

1. 介紹

我們都知道Spring框架的兩大特性分別是 IOC (控制反轉(zhuǎn))和 AOP (面向切面),這個(gè)是每一個(gè)Spring學(xué)習(xí)視頻里面一開(kāi)始都會(huì)提到的。在日常項(xiàng)目中,我們也會(huì)經(jīng)常使用IOC控制反轉(zhuǎn),但是卻感覺(jué)AOP很少會(huì)運(yùn)用到。其實(shí)AOP大有用處,甚至可以讓你偷偷懶。

舉一個(gè)例子,假如現(xiàn)在要讓你記錄每一個(gè)請(qǐng)求的請(qǐng)求IP,請(qǐng)求的方法,請(qǐng)求路徑,請(qǐng)求的參數(shù),返回參數(shù),你會(huì)怎么做?你會(huì)想,那簡(jiǎn)單啊,我直接 log.info("xxxx") 輸出日志不行嗎,簡(jiǎn)單!可是你要想清楚,每個(gè)請(qǐng)求請(qǐng)求的方法不一定是同一個(gè),有一些請(qǐng)求可能請(qǐng)求編輯方法,另外一些請(qǐng)求可能請(qǐng)求登錄方法,這么多方法,你每一個(gè)方法下面都重復(fù)寫(xiě)了差不多6,7行重復(fù)代碼,你覺(jué)得這好嗎?

這里,如果我們使用Aop來(lái)記錄日志,那是再好不過(guò)了。我們可以看看一個(gè)方法的執(zhí)行過(guò)程來(lái)理解AOP。

下面再來(lái)看使用AOP后的執(zhí)行過(guò)程。

AOP是面向切面編程,面向切面思想就是讓我們把程序想象成一條一條管道連接起來(lái)的大管道,而AOP就是在管道和管道之間的過(guò)濾網(wǎng),能夠在不影響管道的情況下對(duì)管道中傳輸?shù)臄?shù)據(jù)進(jìn)行記錄,修改。

使用AOP我們可以很方便地進(jìn)行操作日志記錄,性能日志記錄,請(qǐng)求日志記錄,事務(wù)操作,安全管理等。這么說(shuō)可能很抽象,再詳細(xì)點(diǎn)說(shuō)就是各種日志記錄我們可以利用AOP來(lái)進(jìn)行記錄,而不用在業(yè)務(wù)邏輯代碼中插入,安全管理就是我們可以在請(qǐng)求進(jìn)來(lái)前對(duì)請(qǐng)求中的數(shù)據(jù)進(jìn)行解密,在請(qǐng)求返回的時(shí)候?qū)?shù)據(jù)進(jìn)行加密。這么說(shuō)AOP很像Java里面的攔截器,過(guò)濾器和監(jiān)聽(tīng)器的結(jié)合。

具體AOP的原理就不細(xì)講了,那是另外一篇文章了,有關(guān)于動(dòng)態(tài)代理。

2. 實(shí)踐

說(shuō)了這么多,大白話就是AOP能讓我們?cè)诓挥绊懺a的基礎(chǔ)上,對(duì)代碼功能進(jìn)行添加,修改

在實(shí)現(xiàn)日志記錄功能前,我們要先復(fù)習(xí)一下 Spring Aop 里面的通知順序(連接點(diǎn),通知還不知道是什么的,先去B站看一下Spring初級(jí)教程)。

先把Aop的starter依賴(lài)添加進(jìn)pom文件中。

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

2.1 定義注解

那現(xiàn)在我們來(lái)自定義一個(gè)注解,目的是標(biāo)注該注解的方法將會(huì)記錄調(diào)用該方法的請(qǐng)求信息

@Retention(RetentionPolicy.RUNTIME)
@Target({ElementType.METHOD})
@Documented
public @interface MyLog {
    String value() default "";
}

注解不是本篇重點(diǎn),有興趣的童鞋可以搜一下。

2.2 切面類(lèi)

定義我們的日志記錄切面類(lèi),切面類(lèi)中記錄請(qǐng)求的信息。

@Component
@Aspect
@Slf4j
public class LogAspect {
 
    //切入點(diǎn)為自定義注解
    @Pointcut("@annotation(com.example.springaopdemo.demo2.MyLog)")
    public void MyLog(){}
 
 
    @Before("MyLog()")
    public void Before(JoinPoint jp){
        //獲取HttpServletRequest對(duì)象
        ServletRequestAttributes requestAttributes = (ServletRequestAttributes) RequestContextHolder.getRequestAttributes();
        assert requestAttributes != null;
        HttpServletRequest request = requestAttributes.getRequest();
        log.info("==========請(qǐng)求信息==========");
        log.info("請(qǐng)求鏈接 : {}",request.getRequestURL().toString());
        log.info("Http Method : {}",request.getMethod());
        log.info("Class Method : {}.{}",jp.getSignature().getDeclaringTypeName(),jp.getSignature().getName());
        log.info("Ip : {}",request.getRemoteAddr());
        log.info("Args : {}", Arrays.asList(jp.getArgs()));
    }
 
    @Around("MyLog()")
    public Object Around(ProceedingJoinPoint proceedingJoinPoint) throws Throwable {
        long startTime = System.currentTimeMillis();
        Object result = proceedingJoinPoint.proceed();
        log.info("執(zhí)行時(shí)間 : {} ms", System.currentTimeMillis() - startTime);
        log.info("返回參數(shù) : {}", result);
        return result;
    }
}

通過(guò) @Around 環(huán)繞通知我們可以進(jìn)行簡(jiǎn)單的性能記錄,如果加上 Oshi 我們甚至可以記錄執(zhí)行該方法前后的CPU,內(nèi)存占用率。

Oshi是Java的免費(fèi)基于JNA的操作系統(tǒng)和硬件信息庫(kù),Github地址是:https://github.com/oshi/oshi
它的優(yōu)點(diǎn)是不需要安裝任何其他本機(jī)庫(kù),并且旨在提供一種跨平臺(tái)的實(shí)現(xiàn)來(lái)檢索系統(tǒng)信息,例如操作系統(tǒng)版本,進(jìn)程,內(nèi)存和CPU使用率,磁盤(pán)和分區(qū),設(shè)備,傳感器等。

2.3 編寫(xiě)測(cè)試方法

編寫(xiě)一個(gè)簡(jiǎn)單的請(qǐng)求,請(qǐng)求需要一個(gè)User對(duì)象的請(qǐng)求體,返回一個(gè)Map結(jié)果。

@RestController
@Slf4j
public class Controller {
 
    @PostMapping("/test")
    @MyLog
    public Map<String, Object> testAop(@RequestBody User user){
        Map<String,Object> map = new HashMap<>();
        map.put("code",200);
        map.put("errorMsg","success");
        return map;
    }
}

2.4 運(yùn)行結(jié)果

使用IDEA自帶的Http Client來(lái)測(cè)試api

結(jié)果:

可以看到通過(guò)利用AOP,我們沒(méi)有修改Controller中的代碼,就可以實(shí)現(xiàn)對(duì)Controller中每個(gè)方法請(qǐng)求信息的日志記錄功能。

而且我們還能夠指定該切面類(lèi)是在生產(chǎn)環(huán)境還是開(kāi)發(fā)環(huán)境下生效,只需要在切面類(lèi)上添加注解。

@Profile({"dev"})

然后在配置文件中定義 spring.profiles.active 的屬性即可。

3. 總結(jié)

因?yàn)閷W(xué)習(xí)了Spring后,雖然知道有AOP這個(gè)東西,但是卻從來(lái)沒(méi)有真正的在實(shí)際項(xiàng)目中運(yùn)用,這幾天研究日志記錄,卻發(fā)現(xiàn)AOP在日志記錄中的妙用,甚至可以利用AOP在對(duì)代碼無(wú)侵入的情況下,進(jìn)行參數(shù)數(shù)據(jù)的加密和解密操作。但是,雖然說(shuō)AOP使用方便,但是不能夠?yàn)E用,畢竟AOP底層使用動(dòng)態(tài)代理,而動(dòng)態(tài)代理要做到對(duì)方法的修改就肯定要使用到反射,反射會(huì)對(duì)性能有影響。

4. 參考文章

(7 封私信 / 66 條消息) 在一個(gè)完整的項(xiàng)目中,會(huì)用AOP技術(shù)么,能用簡(jiǎn)單易懂的方式說(shuō)明下什么是AOP么? - 知乎 (zhihu.com)

【SpringBoot】AOP應(yīng)用實(shí)例_sysu_lluozh-CSDN博客

(20條消息) Springboot Aop 自定義注解、切面_張同學(xué)的博客-CSDN博客_springboot 自定義注解切面

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

相關(guān)文章

  • 詳解Java 序列化與反序列化(Serialization)

    詳解Java 序列化與反序列化(Serialization)

    這篇文章主要介紹了Java 序列化與反序列化(Serialization),文中通過(guò)示例代碼介紹的非常詳細(xì),對(duì)大家的學(xué)習(xí)或者工作具有一定的參考學(xué)習(xí)價(jià)值,需要的朋友們下面隨著小編來(lái)一起學(xué)習(xí)學(xué)習(xí) 吧
    2019-03-03
  • 詳解如何繼承Mybatis中Mapper.xml文件

    詳解如何繼承Mybatis中Mapper.xml文件

    這篇文章主要為大家介紹了詳解如何繼承Mybatis中Mapper.xml文件,有需要的朋友可以借鑒參考下,希望能夠有所幫助,祝大家多多進(jìn)步,早日升職加薪
    2022-09-09
  • Java的jstack命令使用示例詳解

    Java的jstack命令使用示例詳解

    jstack 命令非常的簡(jiǎn)單,我們可以通過(guò) jstack -h 或者 jstack -help 命令查看它的用法詳情,今天通過(guò)本文重點(diǎn)給大家介紹Java的jstack命令使用,感興趣的朋友一起看看吧
    2022-03-03
  • Java 多線程同步 鎖機(jī)制與synchronized深入解析

    Java 多線程同步 鎖機(jī)制與synchronized深入解析

    從尺寸上講,同步代碼塊比同步方法小。你可以把同步代碼塊看成是沒(méi)上鎖房間里的一塊用帶鎖的屏風(fēng)隔開(kāi)的空間
    2013-09-09
  • Java中集合LinkedList的原理與使用方法

    Java中集合LinkedList的原理與使用方法

    這篇文章主要給大家介紹了關(guān)于Java中集合LinkedList的原理與使用方法,文中通過(guò)示例代碼介紹的非常詳細(xì),對(duì)大家的學(xué)習(xí)或者工作具有一定的參考學(xué)習(xí)價(jià)值,需要的朋友們下面來(lái)一起學(xué)習(xí)學(xué)習(xí)吧
    2019-06-06
  • Java利用哈夫曼編碼實(shí)現(xiàn)字符串壓縮

    Java利用哈夫曼編碼實(shí)現(xiàn)字符串壓縮

    赫夫曼編碼也翻譯為?哈夫曼編碼(Huffman?Coding),又稱(chēng)霍夫曼編碼,是一種編碼方式,?屬于一種程序算法。本文將利用哈夫曼樹(shù)實(shí)現(xiàn)哈夫曼編碼進(jìn)行字符串壓縮,需要的可以參考一下
    2022-09-09
  • 淺談Java中的class類(lèi)

    淺談Java中的class類(lèi)

    這篇文章主要介紹了淺談Java中的class類(lèi),具有一定借鑒價(jià)值,需要的朋友可以參考下
    2018-01-01
  • Java通俗易懂系列設(shè)計(jì)模式之建造者模式

    Java通俗易懂系列設(shè)計(jì)模式之建造者模式

    這篇文章主要介紹了Java通俗易懂系列設(shè)計(jì)模式之建造者模式,對(duì)設(shè)計(jì)模式感興趣的讀者,一定要看一下
    2021-04-04
  • java ArrayList.remove()的三種錯(cuò)誤用法以及六種正確用法詳解

    java ArrayList.remove()的三種錯(cuò)誤用法以及六種正確用法詳解

    這篇文章主要介紹了java ArrayList.remove()的三種錯(cuò)誤用法以及六種正確用法詳解,文中通過(guò)示例代碼介紹的非常詳細(xì),對(duì)大家的學(xué)習(xí)或者工作具有一定的參考學(xué)習(xí)價(jià)值,需要的朋友們下面隨著小編來(lái)一起學(xué)習(xí)學(xué)習(xí)吧
    2020-01-01
  • java.lang.NoSuchMethodException: com.sun.proxy.$Proxy58.list錯(cuò)誤解決辦法

    java.lang.NoSuchMethodException: com.sun.proxy.$Proxy58.list

    這篇文章主要介紹了java.lang.NoSuchMethodException: com.sun.proxy.$Proxy58.list錯(cuò)誤解決辦法的相關(guān)資料,需要的朋友可以參考下
    2016-12-12

最新評(píng)論