<output id="qn6qe"></output>

    1. <output id="qn6qe"><tt id="qn6qe"></tt></output>
    2. <strike id="qn6qe"></strike>

      亚洲 日本 欧洲 欧美 视频,日韩中文字幕有码av,一本一道av中文字幕无码,国产线播放免费人成视频播放,人妻少妇偷人无码视频,日夜啪啪一区二区三区,国产尤物精品自在拍视频首页,久热这里只有精品12
      Fork me on GitHub

      SpringBoot中搭配AOP實現自定義注解

      1 springBoot的依賴

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

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

      2 自定義注解的步驟

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

      2.1 定義注解類

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

      
      @Target(ElementType.METHOD) // 指定注解的適用范圍
      @Retention(RetentionPolicy.RUNTIME) //指定運行時
      public @interface ApiLog {
      
          String desc() default "";
      
          boolean timeSpan() default true;
      
      
      }
      

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

      2.2 定義切面

      通過@Aspect注解指定一個類,該類必須實現

      @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();
              //獲取被調用方法
              Method method = signature.getMethod();
              //取出被調用方法的注解,方便后續使用注解中的屬性
              ApiLog loglinstener = method.getAnnotation(ApiLog.class);
              log.info("----------------------method[{}]start--------------------",method.getName());
              log.info("方法描述:{}",loglinstener.desc());
              log.info("參數 :{}",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 關于Target注解補充

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

      ElementType的枚舉值有

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

      3.2 關于Retention注解補充

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

      RetentionPolic的枚舉值

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

      3.3 關于AOP的一些概念補充

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

      切面(Aspect)

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

      @Component
      @Aspect
      public class LogAspect {
      }
      

      目標對象(target)

      目標對象指將要被增強的對象,即包含主業務邏輯的類對象。或者說是被一個或者多個切面所通知的對象。

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

      連接點(JoinPoint)

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

      • 方法(表示程序執行點,即在哪個目標方法)
      • 相對點(表示方位,即目標方法的什么位置,比如調用前,后等)

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

      切入點(PointCut)

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

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

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

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

      通知(Advice)

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

      // @Before說明這是一個前置通知,log函數中是要前置執行的代碼,JoinPoint是連接點,
      @Before("pointcut()")
      public void log(JoinPoint joinPoint) { 
      }
      
      //@After 為后置通知
      
      //@Around 為環繞通知
      

      織入(Weaving)

      這里的織入概念是個動作,即Spring將前面的切面、連接點、切入點關聯起來并創建通知代理的過程。織入可以在編譯時,類加載時和運行時完成。在編譯時進行織入就是靜態代理,而在運行時進行織入則是動態代理。

      增強器(Adviser)

      Advisor是切面的另外一種實現,能夠將通知以更為復雜的方式織入到目標對象中,是將通知包裝為更復雜切面的裝配器。Advisor由切入點和Advice組成。 Advisor這個概念來自于Spring對AOP的支撐,在AspectJ中是沒有等價的概念的。Advisor就像是一個小的自包含的切面,這個切面只有一個通知。切面自身通過一個Bean表示,并且必須實現一個默認接口。

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

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

      @Component
      @Aspect
      @Sl4fj
      public class ElasticSearchExecuteLog {
       
        // 不使用注解,而通過基礎的規則配置選擇切入點,表達式是指com.gcc.controller
       // 包下的所有類的所有方法
       @Pointcut("execution(* com.gcc.controller..*(..))")
       public void aspect() {}
       
        // 通知,在符合aspect切入點的方法前插入如下代碼,并且將連接點作為參數傳遞
       @Before("aspect()")
       public void log(JoinPoint joinPoint) { //連接點作為參數傳入
         // 獲得類名,方法名,參數和參數名稱。
         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 關于AOP中一些類及函數的使用

      JoinPoint對象

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

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

      ProceedingJoinPoint對象

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

      Object proceed() throws Throwable //執行目標方法
      Object proceed(Object[] var1) throws Throwable //傳入的新的參數去執行目標方法

      posted @ 2022-12-08 16:51  糖拌西紅柿  閱讀(1485)  評論(0)    收藏  舉報
      主站蜘蛛池模板: 国产精品久久久久久影视| 国产午夜伦伦午夜伦无码| 日韩一区二区三区理伦片| 少妇人妻偷人精品免费视频| 黑人猛精品一区二区三区| 国产对白老熟女正在播放| 欧美一区二区三区成人久久片| 男女一级国产片免费视频| 免费 黄 色 人成 视频 在 线| 日本黄漫动漫在线观看视频| 长腿校花无力呻吟娇喘| 国产精品一区中文字幕| 在线观看特色大片免费视频| 青青草成人免费自拍视频| 亚洲精品一区二区妖精| 五月婷婷激情第四季| 国产精品亚洲二区在线播放| 日产精品99久久久久久| 亚洲 日本 欧洲 欧美 视频| 日韩av日韩av在线| 人妻精品动漫H无码中字| 最新亚洲人成网站在线观看| 激情国产一区二区三区四区| 国产又色又刺激高潮视频| 国产精品中文一区二区| 欧美乱码卡一卡二卡四卡免费| 台湾佬自拍偷区亚洲综合| 欧美日韩精品一区二区三区高清视频 | 韩国福利视频一区二区三区| 亚洲熟妇在线视频观看| 国产亚洲精品第一综合另类无码无遮挡又大又爽又黄的视频 | 色99久久久久高潮综合影院| 国产乱码日产乱码精品精| 一区二区三区精品偷拍| 成人免费无码大片A毛片抽搐色欲| 国产午夜福利高清在线观看| 国产精品成人免费视频网站京东| 国产一区二区三区AV在线无码观看| 精品国产不卡在线观看免费| 亚洲人成网线在线播放VA| A毛片终身免费观看网站|