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

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

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

      [源碼系列:手寫spring] AOP第一節(jié):切點表達式

              在本專欄之前的文章中已經(jīng)帶大家熟悉了Spirng中核心概念IOC的原理以及手寫了核心代碼,接下來將繼續(xù)介紹Spring中另一核心概念AOP。
              AOP即切面編程是Spring框架中的一個關鍵概念,它允許開發(fā)者在應用程序中優(yōu)雅地處理橫切關注點,如日志記錄、性能監(jiān)控和事務管理。在切面編程中,切點表達式是一項關鍵技術,它定義了在何處應用切面的邏輯。本章將深入探討Spring切點表達式的實現(xiàn)原理,為讀者提供對這一重要概念的深刻理解。

      1.AOP案例

      1.1 案例背景

              假設我們有一個在線商城的Web應用,用戶可以瀏覽商品、下單購買商品等。我們希望記錄每個HTTP請求的開始時間、結束時間以及執(zhí)行時間,以便監(jiān)控應用的性能并快速定位潛在的問題。

      1.2 AOP解決方案

      我們可以使用Spring AOP和切點表達式來實現(xiàn)這個日志記錄功能。以下是實現(xiàn)步驟:


      1. 創(chuàng)建一個切面類:

      import org.aspectj.lang.JoinPoint;
      import org.aspectj.lang.annotation.After;
      import org.aspectj.lang.annotation.Aspect;
      import org.aspectj.lang.annotation.Before;
      import org.springframework.stereotype.Component;
      
      @Aspect
      @Component
      public class RequestLoggingAspect {
      
          private long startTime;
      
          @Before("execution(* com.example.controller.*.*(..))")
          public void logBefore(JoinPoint joinPoint) {
              startTime = System.currentTimeMillis();
              System.out.println("Request received for: " + joinPoint.getSignature().toShortString());
          }
      
          @After("execution(* com.example.controller.*.*(..))")
          public void logAfter(JoinPoint joinPoint) {
              long endTime = System.currentTimeMillis();
              long executionTime = endTime - startTime;
              System.out.println("Request completed for: " + joinPoint.getSignature().toShortString());
              System.out.println("Execution Time: " + executionTime + "ms");
          }
      }
      

      上述代碼定義了一個切面類 RequestLoggingAspect,其中包含兩個通知方法 logBeforelogAfterlogBefore 方法在方法執(zhí)行前記錄開始時間和請求信息,而 logAfter 方法在方法執(zhí)行后記錄結束時間和執(zhí)行時間。 

      2. 配置切點表達式:

              在切面類中,我們使用 @Before@After 注解分別標注了 logBeforelogAfter 方法,并指定了切點表達式 "execution(* com.example.controller.*.*(..))"。這個切點表達式表示我們希望攔截所有 com.example.controller 包下的方法執(zhí)行。
       

      3. 啟用AspectJ支持:

      確保在Spring配置文件中啟用了AspectJ的支持。可以通過以下配置實現(xiàn):

      <aop:aspectj-autoproxy />

       在Spring Boot應用的配置類中,保證@Aspect標記的切面類正確被容器管理即可。

      4. 結果:

              當用戶發(fā)起HTTP請求時,切面會自動攔截匹配的方法,記錄請求的開始時間和結束時間,并輸出到日志中。這樣,我們就能夠實時監(jiān)控每個請求的性能,并在需要時進行故障排除。

      2. 知識補充

      2.1 切點和連接點的概念 

              在Spring框架中,切點(Pointcut)和連接點(JoinPoint)是實現(xiàn)切面編程的兩個核心概念。切點定義了在應用程序中哪些地方切入(或觸發(fā))切面的邏輯,而連接點則代表在應用程序執(zhí)行過程中的具體執(zhí)行點。連接點可以是方法的調(diào)用、方法的執(zhí)行、異常的拋出等。理解這兩個概念是理解切點表達式的基礎。

      •  連接點(JoinPoint)是程序執(zhí)行的特定點,它可以是方法的執(zhí)行、方法的調(diào)用、對象的創(chuàng)建等。在Spring AOP中,連接點通常表示方法的執(zhí)行。連接點是AOP切面可以插入的地方,例如,我們可以在方法調(diào)用之前或之后插入額外的邏輯。
      • 切點(Pointcut)是一個表達式,它定義了連接點的集合。換句話說,切點確定了在哪些連接點上切入切面邏輯。Spring框架支持多種切點表達式的定義,其中最常用的是AspectJ切點表達式。

      2.1.1 AspectJ切點表達式

              AspectJ是一種強大的面向切面編程(AOP)語言,Spring框架引入了AspectJ切點表達式以方便開發(fā)者定義切點。AspectJ切點表達式使用一種類似于正則表達式的語法來匹配連接點。

      AspectJ切點表達式的語法包括以下幾個關鍵部分:

      • execution關鍵字:用于指定要匹配的方法執(zhí)行連接點。
      //匹配com.example.service包中的所有類的所有方法
      execution(* com.example.service.*.*(..))
      • 訪問修飾符和返回類型:可以使用通配符來匹配任意修飾符或返回類型。
      //匹配任何公共方法的執(zhí)行。
      execution(public * com.example.service.*.*(..))
      
      • 包和類的限定符:用于指定包和類的名稱,通配符`*`可用于匹配任意字符。
      //匹配com.example.service包中UserService類的所有方法執(zhí)行。
      execution(* com.example.service.UserService.*(..))
      • 方法名:可以指定具體的方法名或使用通配符匹配多個方法。
      //匹配UserService類中以"get"開頭的所有方法執(zhí)行。
      execution(* com.example.service.UserService.get*(..))
      • 參數(shù)列表:可以使用“ (..) ”來匹配任意參數(shù)列表。
      //匹配UserService類的所有方法執(zhí)行,無論參數(shù)列表如何
      execution(* com.example.service.UserService.*(..))

              AspectJ切點表達式的靈活性使開發(fā)者能夠定義精確的切點,以滿足不同的應用需求。通過深入學習和掌握AspectJ切點表達式,開發(fā)者可以更好地利用Spring AOP來管理應用程序中的橫切關注點。接下來,我們將深入研究切點表達式的實現(xiàn)原理,以更好地理解Spring框架是如何解析和匹配這些表達式的。


      3. 實現(xiàn)原理

      3.1代碼分支

      https://github.com/yihuiaa/little-spring/tree/pointcut-expressionicon-default.png?t=N7T8https://github.com/yihuiaa/little-spring/tree/pointcut-expression

      3.2 核心代碼

      ClassFilter 和 MethodMatcher 接口

      • ClassFilter:該接口用于篩選出應該應用切面的目標類。在Pointcut表達式中,如果沒有指定特定的目標類,ClassFilter將返回true,表示匹配任何類。否則,它將根據(jù)指定的規(guī)則篩選出匹配的類。
      • MethodMatcher:這個接口用于匹配目標類中的方法。MethodMatcher決定了哪些方法會成為連接點,從而被切面攔截。MethodMatcher接口包括兩個方法:`matches(Method method, Class<?> targetClass)` 用于匹配方法,和 `isRuntime()` 用于表示匹配是否需要在運行時進行動態(tài)計算。

      AspectJExpressionPointcut 的簡單實現(xiàn)

      • 表達式解析:首先,AspectJExpressionPointcut會將切點表達式進行解析,將其轉化為內(nèi)部的數(shù)據(jù)結構,以便進行進一步處理。這個解析過程涉及到詞法分析和語法分析,以確保切點表達式的語法正確性。
      • 連接點匹配:一旦切點表達式被解析,AspectJExpressionPointcut 將會使用 ClassFilter 和 MethodMatcher 接口來匹配連接點。它會遍歷應用程序中的類和方法,根據(jù)表達式的定義,確定哪些連接點符合切點表達式的要求。
      • 運行時動態(tài)匹配:在某些情況下,切點表達式可能需要在運行時動態(tài)計算。例如,當表達式中包含參數(shù)綁定時,需要在實際方法執(zhí)行時才能確定是否匹配。AspectJExpressionPointcut會在運行時進行動態(tài)匹配,以確保準確的連接點匹配。

      下面將借助aspectjweaver的功能簡單實現(xiàn)Spring AOP切點表達式功能,實現(xiàn)對execution函數(shù)的支持。


      3.2.1 首先添加maven坐標

              <dependency>
                  <groupId>org.aspectj</groupId>
                  <artifactId>aspectjweaver</artifactId>
                  <version>1.8.0</version>
              </dependency>
      特征Spring AOPAspectJ
      編程模型 基于代理的編程模型,使用 Spring 代理生成 AOP 代理。 純粹基于注解或 XML 的編程模型,使用 AspectJ 編譯器或運行時織入器。
      編織方式 運行時織入,通過代理包裝目標對象來添加切面行為。 支持編譯時織入和運行時織入,更靈活且功能更強大。
      性能 由于使用代理,性能開銷較小,但有些限制。 性能較好,編譯時織入可以最小化運行時開銷。
      支持的切入點表達式(Pointcut) 僅支持一部分切入點表達式,如方法執(zhí)行(execution)。 支持廣泛的切入點表達式,包括訪問、調(diào)用、初始化等多種方式。
      復雜度 適用于簡單的切面需求,易于配置和使用。 適用于復雜的切面需求,提供更多高級功能和靈活性。
      集成度 緊密集成到 Spring 框架中,易于使用和配置。 相對獨立,需要額外配置 AspectJ 編譯器或運行時織入器。
      配置方式 使用 Spring 的注解或 XML 配置來定義切面。 使用 AspectJ 注解或 XML 配置來定義切面。

      3.2.2 ClassFilter接口

      public interface ClassFilter {
          boolean matches(Class<?> clazz);
      }
      

      3.2.3 MethodMatcher接口

      public interface MethodMatcher {
          boolean matches(Method method, Class<?> targetClass);
      }

      3.2.4 Pointcut 切點接口

      public interface Pointcut {
          ClassFilter getClassFilter();
      
          MethodMatcher getMethodMatcher();
      }
      

      3.2.5 AspectJExpressionPointcut 切點表達式類

      /**
       * ● @author: YiHui
       * ● @date: Created in 17:33  2023/9/24
       * ● @Description: 這是一個自定義的 AspectJ 表達式切點,用于在 Spring AOP 中匹配切點表達式。
       */
      public class AspectJExpressionPointcut implements Pointcut, ClassFilter, MethodMatcher {
      
          // 支持的切點原語集合
          private static final Set<PointcutPrimitive> SUPPORTED_PRIMITIVES = new HashSet<>();
      
          static {
              // 添加支持的切點原語。在此示例中,我們僅支持 EXECUTION 原語,您可以根據(jù)需要添加更多。
              SUPPORTED_PRIMITIVES.add(PointcutPrimitive.EXECUTION);
          }
      
          // 切點表達式對象,用于解析和匹配切點
          private final PointcutExpression pointcutExpression;
      
          /**
           * 構造函數(shù),用給定的表達式創(chuàng)建 AspectJ 表達式切點。
           *
           * @param expression 切點表達式,用于定義匹配的切點
           */
          public AspectJExpressionPointcut(String expression) {
              // 創(chuàng)建一個 PointcutParser 實例,用于解析切點表達式
              PointcutParser pointcutParser = PointcutParser.getPointcutParserSupportingSpecifiedPrimitivesAndUsingSpecifiedClassLoaderForResolution(
                  SUPPORTED_PRIMITIVES, this.getClass().getClassLoader());
      
              // 解析給定的切點表達式并將其分配給成員變量 pointcutExpression
              pointcutExpression = pointcutParser.parsePointcutExpression(expression);
          }
      
          /**
           * 檢查給定的類是否符合切點表達式的條件。
           *
           * @param clazz 要檢查的類
           * @return 如果類匹配切點表達式,則返回 true,否則返回 false
           */
          @Override
          public boolean matches(Class<?> clazz) {
              return pointcutExpression.couldMatchJoinPointsInType(clazz);
          }
      
          /**
           * 檢查給定的方法是否符合切點表達式的條件。
           *
           * @param method      要檢查的方法
           * @param targetClass 方法所屬的目標類
           * @return 如果方法匹配切點表達式,則返回 true,否則返回 false
           */
          @Override
          public boolean matches(Method method, Class<?> targetClass) {
              // 使用切點表達式檢查方法執(zhí)行是否匹配
              return pointcutExpression.matchesMethodExecution(method).alwaysMatches();
          }
      
          /**
           * 獲取用于類篩選的 ClassFilter 實例。
           *
           * @return ClassFilter 實例,用于過濾匹配的類
           */
          @Override
          public ClassFilter getClassFilter() {
              return this;
          }
      
          /**
           * 獲取用于方法匹配的 MethodMatcher 實例。
           *
           * @return MethodMatcher 實例,用于匹配符合切點表達式的方法
           */
          @Override
          public MethodMatcher getMethodMatcher() {
              return this;
          }
      }
      

      4. 測試

      4.1測試代碼

      public class HelloService {
         public String hello() {
              System.out.println("hello word! yihuiComeOn");
              return "hello word! yihuiComeOn";
          }
      }
      public class PointcutExpressionTest {
          @Test
          public void testPointcutExpression() throws Exception {
              AspectJExpressionPointcut pointcut = new AspectJExpressionPointcut("execution(* service.HelloService.*(..))");
              Class<HelloService> clazz = HelloService.class;
              Method method = clazz.getDeclaredMethod("hello");
      
              System.out.println("切點表達式匹配結果-類匹配:"+pointcut.matches(clazz));
              System.out.println("切點表達式匹配結果-方法匹配:"+pointcut.matches(method, clazz));
          }
      }

      4.2 測試結果

      切點表達式匹配結果-類匹配:true
      切點表達式匹配結果-方法匹配:true





       

       
      posted @ 2023-09-24 18:28  yihuiComeOn  閱讀(43)  評論(0)    收藏  舉報  來源
      主站蜘蛛池模板: 久久综合老鸭窝色综合久久| 91在线国内在线播放老师 | 亚洲熟妇在线视频观看| 2021亚洲va在线va天堂va国产| 99在线精品视频观看免费| 伊人精品成人久久综合97| av无码av无码专区| 国产蜜臀一区二区三区四区 | 国日韩精品一区二区三区| 亚洲中文字幕国产综合| 精品无码成人片一区二区| 国产成人精品一区二区三区| 66亚洲一卡2卡新区成片发布| 99久久久国产精品免费无卡顿| 人妻无码久久久久久久久久久 | 另类 亚洲 图片 激情 欧美| 亚洲人成色7777在线观看不卡 | 久久精品国产九一九九九| 免费AV片在线观看网址| 精品人妻中文字幕在线| 久久精品国产99久久6| 无码av最新无码av专区| 色综合久久久久综合体桃花网| 2019nv天堂香蕉在线观看| 激情综合色区网激情五月| 久久精品国产蜜臀av| 亚洲精品宾馆在线精品酒店| 亚洲日本中文字幕天天更新| 久久久久久免费一区二区三区| 熟女视频一区二区三区嫩草| 亚洲欧美高清在线精品一区二区| 熟妇的奶头又大又长奶水视频 | 91精品久久久久久无码人妻| 97欧美精品系列一区二区| 日本久久香蕉一本一道| 精品亚洲AⅤ无码午夜在线| 日韩一区二区三区女优丝袜| 亚洲乱熟乱熟女一区二区| 国产免费无遮挡吸奶头视频| 天天天做夜夜夜做无码| 国产美女自卫慰黄网站|