spring03-aop

spring03-AOP


  1. 術語:
    1. joinPoint(鏈接點):
      鏈接點指的是被攔截的點, 在spring中指的就是配置了動態代理的類中的全部方法
    2. pointCut(切入點):
      切入點就是被加強的方法
    3. advice(通知):
      通知指的就是加強方法具體作了什麼, 實際上就是指提供了代理方法的類, 分爲前置通知, 後置通知, 異常通知, 最終通知, 環繞通知
    4. introduction(引介):
      引介是一種特殊的通知. 在不修改類代碼的前提下, introduction能夠在運行期間爲類動態的添加一些方法或field
    5. target(目標對象):
      被代理對象
    6. weaving(織入):
      指把加強應用到目標對象產生代理對象的過程.
      spring採用動態代理植入, aspectJ使用編譯期織入和類裝載期織入
    7. proxy(代理):
      一個類被aop織入後產生的代理對象
  2. aop的xml配置步驟
    1. 將通知類添加到spring容器
    2. 使用 aop:config 標籤開始配置aop
    3. 使用 aop:aspect 標籤配置切面
      1. id: 惟一標識
      2. ref: 指定通知類的bean的id
    4. 在 aop:aspect 內部使用相應標籤配置通知類型
      1. 通知標籤:
        • method: 指定通知方法
        • pointcut: 指定切入點表達式, 用於指定對哪些方法進行增強
          切入點表達式寫法: execution(訪問修飾符 返回值 全限定方法名(參數表))
          • public void cn.ann.service.AccountService.saveAccount()
          • 其中:
            1. 訪問修飾符能夠省略
            2. 返回值能夠使用通配符, 表示任意返回值
            3. 包名能夠只用通配符, 表示任意包
            4. 包名能夠使用 .. 表示當前包及其子包
            5. 類名和方法名也能夠使用通配符
            6. 參數表:
              • 能夠直接寫數據類型: 基本類型直接寫名稱: int; 引用類型寫全限定類名
              • 能夠使用通配符表明全部參數, 可是方法必須有參數才能夠
              • 能夠使用 .. 表示有無參數都可, 有參數能夠是任意類型
          • 全通配寫法: * *..*.*(..)
          • 開發中的經常使用寫法:
            * 業務層包名..*.*(..)
            * cn.ann.service..*.*(..)
    5. 通知標籤
      1. aop:before: 前置通知. 切入點執行前執行
      2. aop:after-returning: 後置通知: 切入點正常執行後執行
      3. aop:after-throwing: 異常通知: 切入點產生異常後執行
      4. aop:after: 最終通知: 切入點執行後執行(不管是否產生異常)
      5. aop:around: 環繞通知: spring爲咱們提供的能夠 讓咱們手動設置通知何時執行 的方式
        • 方法設計:git

          // spring提供了ProceedingJoinPoint接口用來讓咱們獲取切入點的信息
          public Object aroundLogging(ProceedingJoinPoint pjp) {
              try {
                  System.out.println("前置 ...");
                  Object ret = pjp.proceed(pjp.getArgs());
                  System.out.println("後置 ...");
                  return ret;
              } catch (Throwable throwable) {
                  System.out.println("異常 ...");
                  throw new RuntimeException(throwable);
              } finally {
                  System.out.println("最終 ...");
              }
          }
      • 後置通知和異常通知只能執行一個
    6. 配置切入點github

      <aop:config>
          <!-- 配置切入點 -->
          <aop:pointcut id="logPointcut" expression="execution(* cn.ann.service..*.*(..))"/>
      </aop:config>
    • aop配置代碼spring

      <!-- 配置AOP -->
      <aop:config>
          <!-- 配置切入點 -->
          <aop:pointcut id="logPointcut" expression="execution(* cn.ann.service..*.*(..))"/>
          <!-- 配置切面 -->
          <aop:aspect id="logAdvice" ref="logger">
              <!-- 前置通知
              <aop:before method="beforeLogging" pointcut-ref="logPointcut"/> -->
              <!-- 後置通知
              <aop:after-returning method="afterReturningLogging" pointcut-ref="logPointcut"/> -->
              <!-- 異常通知
              <aop:after-throwing method="afterThrowingLogging" pointcut-ref="logPointcut"/> -->
              <!-- 最終通知
              <aop:after method="afterLogging" pointcut-ref="logPointcut"/> -->
              <!-- 環繞通知 -->
              <aop:around method="aroundLogging" pointcut-ref="logPointcut"/>
          </aop:aspect>
      </aop:config>
  3. aop註解配置
    1. 開啓註解掃描
      • <context:component-scan base-package="cn.ann"/>
    2. 開啓aop註解
      • <aop:aspectj-autoproxy/>
    3. 配置通知
      1. 將通知類添加到spring容器中: @Component("logger")
      2. 聲明通知類: @Aspect
      3. 配置切入點:express

        @Pointcut("execution(* cn.ann.service..*.*(..))")
        private void logPointcut(){}
      4. 配置通知設計

        @Before("logPointcut()")
        public void beforeLogging(){
            System.out.println("before logging run...");
        }
        
        @AfterReturning("logPointcut()")
        public void afterReturningLogging(){
            System.out.println("afterReturning logging run...");
        }
        
        @AfterThrowing("logPointcut()")
        public void afterThrowingLogging(){
            System.out.println("afterThrowing logging run...");
        }
        
        @After("logPointcut()")
        public void afterLogging(){
            System.out.println("after logging run...");
        }
        
        @Around("logPointcut()")
        public Object aroundLogging(ProceedingJoinPoint pjp) {
            try {
                System.out.println("前置 ...");
                Object ret = pjp.proceed();
                System.out.println("後置 ...");
                return ret;
            } catch (Throwable throwable) {
                System.out.println("異常 ...");
                throw new RuntimeException(throwable);
            } finally {
                System.out.println("最終 ...");
            }
        }
      • 注意:
        1. 分開配置 前置通知, 後置通知, 異常通知, 最終通知 運行會有點問題, 方法的調用順序回頭有點問題
          運行結果
        2. 開發中通常使用環繞通知
          運行結果

本文代碼: 此處 的 spring03-aop代理

相關文章
相關標籤/搜索
本站公眾號
   歡迎關注本站公眾號,獲取更多信息