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

SpringBoot搭配AOP實現(xiàn)自定義注解

 更新時間:2022年12月09日 08:16:32   作者:糖拌西紅柿  
這篇文章主要為大家詳細(xì)介紹了SpringBoot如何搭配AOP實現(xiàn)自定義注解,文中的示例代碼講解詳細(xì),感興趣的小伙伴可以跟隨小編一起學(xué)習(xí)一下

1.springBoot的依賴

確定項目中包含可以注解的依賴

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

2.自定義注解的步驟

在項目中自定義注解的步驟主要有兩步,第一步:定義注解類,第二步:定義切面

2.1定義注解類

直接創(chuàng)建 @interface的類,使用注解@Target和 @Retention指定其適用范圍及保留時長,如下:

@Target(ElementType.METHOD) // 指定注解的適用范圍
@Retention(RetentionPolicy.RUNTIME) //指定運行時
public @interface ApiLog {

    String desc() default "";

    boolean timeSpan() default true;


}

注解類的內(nèi)容一般很簡單,類似于Enum類一樣,里面是簡單的方法及屬性

2.2定義切面

通過@Aspect注解指定一個類,該類必須實現(xiàn)

@Component
@Aspect
@Slf4j(topic = "ApiLogNote")
public class ElasticSearchExecuteLog {

    @Around("@annotation(com.gcc.ApiLog)")
    public Object aroundAdvice(ProceedingJoinPoint point) throws Throwable {
        MethodSignature signature = (MethodSignature) point.getSignature();
        //獲取被調(diào)用方法
        Method method = signature.getMethod();
        //取出被調(diào)用方法的注解,方便后續(xù)使用注解中的屬性
        ApiLog loglinstener = method.getAnnotation(ApiLog.class);
        log.info("----------------------method[{}]start--------------------",method.getName());
        log.info("方法描述:{}",loglinstener.desc());
        log.info("參數(shù) :{}",point.getArgs());
        long startTime = System.currentTimeMillis();
        Object proceed = point.proceed();
        long endTime = System.currentTimeMillis();
        log.info("耗時:{}ss",endTime-startTime);
        log.info("----------------------method[{}] end--------------------\n",method.getName())
        return proceed;
    }
}

2.3使用注解

因為此例子使用的類型為METHOD即方法級的注解,直接在方法上使用即可:

    @ApiLog
    public JSONObject seachEsData(String indexName, SearchSourceBuilder searchSourceBuilder) {
        JSONObject resultMap = new JSONObject();
        .......
        return resultMap;
    }

3.知識點補充

3.1 關(guān)于Target注解補充

注解@Target常常配合枚舉類ElementType來指定注解的作用位置,也叫合法位置,即你定義了一個注解,這個注解是類注解還是方法注解還是XX注解等,具體作用的范圍,取決于@Target({ElementType.TYPE})中,ElementType的枚舉值,在進(jìn)行自定義枚舉時,根據(jù)自己的需求,決定定義的注解是哪類層級使用的注解,例如上面的例子中,@ApiLog這個自定義的注解就是方法級的注解

ElementType的枚舉值有

枚舉值含義
TYPE類, 接口 (包括注解類型), 或 枚舉 聲明
FIELD字段、包括枚舉常量
METHOD方法聲明
PARAMETER正式的參數(shù)聲明
CONSTRUCTOR構(gòu)造函數(shù)的聲明
LOCAL_VARIABLE局部變量的聲明
ANNOTATION_TYPE注解類型的聲明
PACKAGE包聲明

3.2 關(guān)于Retention注解補充

注解@Retention常常配合枚舉類RetentionPolic來指定注解的各種策略,注解的保留時間,也就是何時生效,即你定義了一個注解,這個注解是編譯時生效還是僅僅只是在代碼中標(biāo)記等等,具體作用的范圍,取決于@Retention({RetentionPolic.TYPE})中,RetentionPolic的枚舉值,在進(jìn)行自定義枚舉時,大多數(shù)都是使用RUNTIME(編譯時生效)

RetentionPolic的枚舉值

枚舉值含義
SOURCE解只在源代碼級別保留,編譯時被忽略
CLASS注解將被編譯器在類文件中記錄 , 但在運行時不需要JVM保留。這是默認(rèn)的
RUNTIME注解將被編譯器記錄在類文件中,在運行時保留VM,也是使用最多的(一般自定義均使用這個)

3.3 關(guān)于AOP的一些概念補充

這種在運行時,動態(tài)地將代碼切入到類的指定方法、指定位置上的編程思想就是面向切面的編程

切面

切面是一個橫切關(guān)注點的模塊化,一個切面能夠包含同一個類型的不同增強方法,比如說事務(wù)處理和日志處理可以理解為兩個切面。切面由切入點和通知組成,它既包含了橫切邏輯的定義,也包括了切入點的定義。 Spring AOP就是負(fù)責(zé)實施切面的框架,它將切面所定義的橫切邏輯織入到切面所指定的連接點中。簡單點理解,在SpringBoot中使用了Aspect注解的類就是切面

@Component
@Aspect
public class LogAspect {
}

目標(biāo)對象

目標(biāo)對象指將要被增強的對象,即包含主業(yè)務(wù)邏輯的類對象?;蛘哒f是被一個或者多個切面所通知的對象。

在我們的例子中,即是使用了@ApiLog注解的地方

連接點

程序執(zhí)行過程中明確的點,如方法的調(diào)用或特定的異常被拋出。連接點由兩個信息確定:

方法(表示程序執(zhí)行點,即在哪個目標(biāo)方法)

相對點(表示方位,即目標(biāo)方法的什么位置,比如調(diào)用前,后等)

簡單來說,連接點就是被攔截到的程序執(zhí)行點,因為Spring只支持方法類型的連接點,所以在Spring中連接點就是被攔截到的方法。

切入點

切入點是對連接點進(jìn)行攔截的條件定義。切入點表達(dá)式如何和連接點匹配是AOP的核心,Spring缺省使用AspectJ切入點語法。 一般認(rèn)為,所有的方法都可以認(rèn)為是連接點,但是我們并不希望在所有的方法上都添加通知,而切入點的作用就是提供一組規(guī)則(使用 AspectJ pointcut expression language 來描述) 來匹配連接點,給滿足規(guī)則的連接點添加通知。

//此處的匹配規(guī)則是 com.remcarpediem.test.aop.service包下的所有類的所有函數(shù)。
@Pointcut("execution(* com.remcarpediem.test.aop.service..*(..))")
public void pointcut() {
}

這里切入點的概念其實就是確定對哪些目標(biāo)對象進(jìn)行切面插入功能,一開始的例子是采用注解的方式來達(dá)到切入**點的作用

 @Around("@annotation(com.gcc.ApiLog)")

通知

通知是指攔截到連接點之后要執(zhí)行的代碼,包括了“around”、“before”和“after”等不同類型的通知。Spring AOP框架以攔截器來實現(xiàn)通知模型,并維護(hù)一個以連接點為中心的攔截器鏈。

// @Before說明這是一個前置通知,log函數(shù)中是要前置執(zhí)行的代碼,JoinPoint是連接點,
@Before("pointcut()")
public void log(JoinPoint joinPoint) { 
}

???????//@After 為后置通知

//@Around 為環(huán)繞通知

織入(Weaving)

這里的織入概念是個動作,即Spring將前面的切面、連接點、切入點關(guān)聯(lián)起來并創(chuàng)建通知代理的過程??椚肟梢栽诰幾g時,類加載時和運行時完成。在編譯時進(jìn)行織入就是靜態(tài)代理,而在運行時進(jìn)行織入則是動態(tài)代理。

增強器(Advisor)

Advisor是切面的另外一種實現(xiàn),能夠?qū)⑼ㄖ愿鼮閺?fù)雜的方式織入到目標(biāo)對象中,是將通知包裝為更復(fù)雜切面的裝配器。Advisor由切入點和Advice組成。 Advisor這個概念來自于Spring對AOP的支撐,在AspectJ中是沒有等價的概念的。Advisor就像是一個小的自包含的切面,這個切面只有一個通知。切面自身通過一個Bean表示,并且必須實現(xiàn)一個默認(rèn)接口。

簡單來講,整個 aspect 可以描述為: 滿足 pointcut 規(guī)則的 joinpoint 會被添加相應(yīng)的 advice 操作。

將上方通過注解使用切面的方式改寫一下:

@Component
@Aspect
@Sl4fj
public class ElasticSearchExecuteLog {
 
  // 不使用注解,而通過基礎(chǔ)的規(guī)則配置選擇切入點,表達(dá)式是指com.gcc.controller
 // 包下的所有類的所有方法
 @Pointcut("execution(* com.gcc.controller..*(..))")
 public void aspect() {}
 
  // 通知,在符合aspect切入點的方法前插入如下代碼,并且將連接點作為參數(shù)傳遞
 @Before("aspect()")
 public void log(JoinPoint joinPoint) { //連接點作為參數(shù)傳入
   // 獲得類名,方法名,參數(shù)和參數(shù)名稱。
   Signature signature = joinPoint.getSignature();
   String className = joinPoint.getTarget().getClass().getName();
   String methodName = joinPoint.getSignature().getName();
   Object[] arguments = joinPoint.getArgs();
   MethodSignature methodSignature = (MethodSignature) joinPoint.getSignature();
   String[] argumentNames = methodSignature.getParameterNames();
   StringBuilder sb = new StringBuilder(className + "." + methodName + "(");
       for (int i = 0; i< arguments.length; i++) {
                  Object argument = arguments[i];
                  sb.append(argumentNames[i] + "->");
                  sb.append(argument != null ? argument.toString() : "null ");
       }
   sb.append(")");
   log.info(sb.toString());
  }
}

3.4關(guān)于AOP中一些類及函數(shù)的使用

JoinPoint對象

JoinPoint對象封裝了SpringAop中切面方法的信息,在切面方法中添加JoinPoint參數(shù),就可以獲取到封裝了該方法信息的JoinPoint對象.

方法作用返回對象
getSignature()獲取封裝了署名信息的對象,在該對象中可以獲取到目標(biāo)方法名,所屬類的Class等信息Signature
getArgs()獲取 獲取傳入目標(biāo)方法的參數(shù)對象Object[]
getTarget()獲取被代理的對象Object

proceedingJoinPoin對象

proceedingJoinPoin對象是JoinPoint的子類,在原本JoinPoint的基礎(chǔ)上,放開了Proceeed()的使用,一般在環(huán)繞通知@Around時使用:

Object proceed() throws Throwable //執(zhí)行目標(biāo)方法
Object proceed(Object[] var1) throws Throwable //傳入的新的參數(shù)去執(zhí)行目標(biāo)方法

以上就是SpringBoot搭配AOP實現(xiàn)自定義注解的詳細(xì)內(nèi)容,更多關(guān)于SpringBoot AOP自定義注解的資料請關(guān)注腳本之家其它相關(guān)文章!

相關(guān)文章

  • Java程序開發(fā)環(huán)境配置圖文教程

    Java程序開發(fā)環(huán)境配置圖文教程

    這篇文章主要為大家詳細(xì)介紹了Java程序開發(fā)環(huán)境配置圖文教程,具有一定的參考價值,感興趣的小伙伴們可以參考一下
    2019-07-07
  • SpringBoot使用Redis方式

    SpringBoot使用Redis方式

    文章介紹了SpringDataRedis操作本地Redis數(shù)據(jù)庫的方法,包括Redis的基本概念、數(shù)據(jù)類型、命令以及在Java中的使用
    2024-11-11
  • jdk中動態(tài)代理異常處理分析:UndeclaredThrowableException

    jdk中動態(tài)代理異常處理分析:UndeclaredThrowableException

    最近在工作中遇到了報UndeclaredThrowableException的錯誤,通過查找相關(guān)的資料,終于解決了,所以這篇文章主要給大家介紹了關(guān)于jdk中動態(tài)代理異常處理分析:UndeclaredThrowableException的相關(guān)資料,需要的朋友可以參考下
    2018-04-04
  • 利用Spring Boot操作MongoDB的方法教程

    利用Spring Boot操作MongoDB的方法教程

    mongodb是最早熱門非關(guān)系數(shù)據(jù)庫的之一,使用也比較普遍,一般會用做離線數(shù)據(jù)分析來使用,放到內(nèi)網(wǎng)的居多,下面這篇文章主要給大家介紹了利用Spring Boot操作MongoDB的方法教程,需要的朋友可以參考下
    2017-05-05
  • 親測解決,nacos下線失敗問題

    親測解決,nacos下線失敗問題

    這篇文章主要介紹了親測解決,nacos下線失敗問題,具有很好的參考價值,希望對大家有所幫助,如有錯誤或未考慮完全的地方,望不吝賜教
    2024-07-07
  • Java單例模式實現(xiàn)的幾種方式

    Java單例模式實現(xiàn)的幾種方式

    這篇文章主要介紹了Java單例模式實現(xiàn)的幾種方式的相關(guān)資料,需要的朋友可以參考下
    2016-09-09
  • SpringBoot 整合WebSocket 前端 uniapp 訪問的詳細(xì)方法

    SpringBoot 整合WebSocket 前端 uniapp 訪問的詳細(xì)方法

    這篇文章主要介紹了SpringBoot 整合WebSocket 前端 uniapp 訪問的詳細(xì)方法,本文通過實例代碼給大家介紹的非常詳細(xì),對大家的學(xué)習(xí)或工作具有一定的參考借鑒價值,需要的朋友可以參考下
    2023-09-09
  • 聊聊ResourceBundle和properties讀取配置文件的區(qū)別

    聊聊ResourceBundle和properties讀取配置文件的區(qū)別

    這篇文章主要介紹了ResourceBundle和properties讀取配置文件的區(qū)別,具有很好的參考價值,希望對大家有所幫助。如有錯誤或未考慮完全的地方,望不吝賜教
    2021-07-07
  • Java如何重寫object類的equals方法詳解

    Java如何重寫object類的equals方法詳解

    這篇文章主要給大家介紹了關(guān)于Java如何重寫object類的equals方法的相關(guān)資料,文中通過示例代碼介紹的非常詳細(xì),對大家的學(xué)習(xí)或者工作具有一定的參考學(xué)習(xí)價值,需要的朋友們下面隨著小編來一起學(xué)習(xí)學(xué)習(xí)吧
    2020-12-12
  • java Springboot實現(xiàn)多文件上傳功能

    java Springboot實現(xiàn)多文件上傳功能

    這篇文章主要為大家詳細(xì)介紹了java Springboot實現(xiàn)多文件上傳功能,文中示例代碼介紹的非常詳細(xì),具有一定的參考價值,感興趣的小伙伴們可以參考一下
    2018-08-08

最新評論

隆子县| 政和县| 东海县| 兴宁市| 府谷县| 金川县| 济宁市| 浮山县| 游戏| 延津县| 车险| 芦山县| 洪湖市| 韶山市| 昌宁县| 普格县| 兴隆县| 石楼县| 临江市| 原平市| 靖宇县| 五常市| 蒙阴县| 林芝县| 东乡族自治县| 尤溪县| 深水埗区| 庄浪县| 图木舒克市| 广灵县| 宜兴市| 霸州市| 阿城市| 达拉特旗| 北辰区| 台南县| 崇左市| 普兰店市| 西乌| 铜梁县| 和田市|