日韩性视频-久久久蜜桃-www中文字幕-在线中文字幕av-亚洲欧美一区二区三区四区-撸久久-香蕉视频一区-久久无码精品丰满人妻-国产高潮av-激情福利社-日韩av网址大全-国产精品久久999-日本五十路在线-性欧美在线-久久99精品波多结衣一区-男女午夜免费视频-黑人极品ⅴideos精品欧美棵-人人妻人人澡人人爽精品欧美一区-日韩一区在线看-欧美a级在线免费观看

歡迎訪問 生活随笔!

生活随笔

當前位置: 首頁 > 前端技术 > javascript >内容正文

javascript

SpringDay3

發布時間:2024/1/18 javascript 31 豆豆
生活随笔 收集整理的這篇文章主要介紹了 SpringDay3 小編覺得挺不錯的,現在分享給大家,幫大家做個參考.

文章目錄

  • 前言
  • 一、Aop
  • 二、Aop簡介
      • 1.1)Aop概念
      • 1.2)AOP作用
      • 1.3)AOP優勢
    • 2.AOP入門
      • 2.1)AOP相關概念
      • 2.2)AOP開發過程
        • 2.3)入門分析
    • 3.AOP配置(XML)
      • 3.1)AspectJ
      • 3.2)AOP配置
        • 3.2.1)aop:config
        • 3.2.2)aop:aspect
        • 3.2.3)aop:pointcut
      • 3.3)切入點
      • 3.4)切入點表達式的組成
        • 3.4.1)切入點表達式——關鍵字
        • 3.4.2)切入點表達式——通配符
        • 3.4.3) 切入點表達式——邏輯運算符
        • 3.4.4)切入點表達式——范例
      • 3.5)切入點的三種配置方式
      • 3.6)切入點配置經驗
      • 3.7)通知類型
        • 3.7.1)aop:before
        • 3.7.2)aop:after
        • 3.7.3)aop:after-returning
        • 3.7.4)aop:after-throwing
        • 3.7.5)aop:around
      • 3.8)通知順序
      • 3.9)通知獲取順序
        • 3.9.1)通知獲取參數數據
        • 3.9.2)通知獲取返回值數據
        • 3.9.3)通知獲取異常數據
    • 4)AOP配置(注解)
      • 4.1)注解開發AOP制作步驟
      • 4.2)注解開發AOP注意事項
      • 4.3)AOP注解詳解
        • 4.3.1)@Aspect
        • 4.3.2)@pointcut
        • 4.3.3) @Before
        • 4.3.4)@After
        • 4.3.5)@AfterRuterning
        • 4.3.6)@AfterThrowing
        • 4.3.7)@Around
      • 4.4)AOP注解開發通知執行順序控制
      • 4.5)AOP 注解驅動
    • 5)AOP底層原理
      • 5.1)靜態代理
      • 5.2)動態代理——JDK Proxy
      • 5.3)動態代理CGLIB
      • 5.4)代理模式的選擇
      • 5.5)織入時機
  • 總結


前言

Spring框架的Aop層個人筆記


一、Aop

我理解的AOP:在使用MyBatis時,有大量的重復性代碼,但是最關鍵的sql語句部分又各不相同,從而無法提取處一個共同的類讓我們進行重復調用。進而aop的誕生使這種方法簡便了很多。它是將上下文中重復的代碼部分使用織入的方式在運行期,具體信息在最后一個圖中


二、Aop簡介

1.1)Aop概念

  • AOP(Aspect Oriented Programing)面向對象切面編程,一種編程范式,隸屬于軟件工程范疇,指導開發者如何組織程序結構
  • AOP彌補了OOP(面向對象程序涉及(Object Oriented Programming))基于oop基礎之上進行橫向開發
  • AOP聯盟

1.2)AOP作用

  • 伴隨著AOP時代的降臨,可以從各個行業的標準化、規范化開始入手,一步一步將所有共性功能逐一開發完畢,最終以功能組合來完成個別業務模塊乃至整體業務系統的開發
  • 目標:將軟件開發由手工制作走向半自動化/全自動化階段,實現”插拔式組件體系結構“搭建

1.3)AOP優勢

  • 提高代碼的可重用性
  • 業務代碼編碼更簡潔
  • 業務代碼維護更高效
  • 業務功能擴展更便捷

2.AOP入門

2.1)AOP相關概念

  • joinpoint(連接點):就是方法
  • Pointcut(切入點):就是挖掉共性功能的方法
  • Advice(通知):就是共性功能,最終以一個方法的形式呈現
  • Aspect(切面):就是共性功能與挖的位置的對應關系
  • Target(目標對象):就是挖掉功能的方法對應的類產生的對象,這種對象是無法直接完成最終工作的。
  • Weaving(織入):就是挖掉共性的功能回填的動態過程
  • Proxy(代理):目標對象無法直接完成工作,需要對其進行功能回填,通過創建原始對象的代理對象實現
  • Introduction(引入/引介):就是對原始對象無中生有的添加成員變量或者成員方法

2.2)AOP開發過程

  • 開發階段(開發者完成)

    • 正常的制作過程
    • 將非共性功能開發到對應的目標類對象類中,并制作成切入點方法
    • 將共性功能獨立開發出來,制作成通知
    • 在配置文件中,聲明切入點
    • 在配置文件中,聲明切入點通知間的關系(含通知類型),即切面
  • 運行階段(AOP完成)

    • Spring容器加載配置文件,監控所有配置的切入點方法的執行
    • 當監控到切入點方法被運行,使用代理機制,動態創建目標對象代理對象,根據通知類別,在代理對象的對應位置將通知對應功能織入,完成完整的代碼邏輯并運行

2.3)入門分析

  • 導入相關坐標
  • 確認要抽取的功能,并將其制作成方法保存到專用的類中,刪除原始業務中對應的功能
  • 將所有進行AOP操作的資源加載到IoC容器中
  • 使用配置的方式描述被抽取功能的位置,并描述被抽取功能與對應位置的關系
  • 運行程序
    步驟一:導入坐標
  • <dependency><groupId>org.aspectj</groupId><artifactId>aspectjweaver</artifactId><version>1.9.4</version> </dependency>

    步驟二:在業務層抽取通用代碼

    public class UserServiceImpl implements UserService{public void save(){//原始功能執行前執行的通用功能——日志記錄System.out.println("write log...");//原始功能System.out.println("account service running...");} }public class AOPAdvice {public void logAdvice(){System.out.println("write log...");} }

    步驟三:把通知加入spring容器管理

    <?xml version="1.0" encoding="UTF-8"><beans xmlns="http://www.springframework.org/schema/beans"xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"xmlns:p="http://www.springframework.org/schema/p"xmlns:context="http://www.springframework.org/schema/context"xmlns:aop="http://www.springframework.org/schema/aop"xsi:schemaLocation="http://www.springframework.org/schema/beanshttps://www.springframework.org/schema/beans/spring-beans.xsdhttp://www.springframework.org/schema/contexthttps://www.springframework.org/schema/context/spring-context.xsdhttp://www.springframework.org/schema/aophttps://www.springframework.org/schema/aop/spring-aop.xsd"><!--原始的功能要配置成spring控制的資源--><bean id="userService" class="com.***.service.impl.UserserviceImpl"/><!--抽取的功能要配置成spring控制的資源--><bean id="myAdvice" class="com.***.aop.AopAdvice"/> </bean>

    步驟四:在配置文件中配置aop的配置

    <!--aop配置--> <aop:config><!--配置切入點--><aop:pointcut id="pt" experession="execution(* *..*())"/><!--配置切面--><aop:aspect ref="myAdvice"><!--通知與切入點之間的關系--><aop:before method="logAdvice" pointcut-ref="pt"/></aop:aspect ref="myAdvice"> </aop:config>

    3.AOP配置(XML)

    3.1)AspectJ

    • Aspect(切面)用于描述切入點與通知間的關系,是AOP編程中的一個概念
    • AspectJ是基于java語言對Aspect的實現

    3.2)AOP配置

    3.2.1)aop:config

    • 名稱:aop:config
    • 類型:標簽
    • 歸屬:beans標簽
    • 作用:設置AOP
    • 格式
    <beans><aop:config>……</aop:config><aop:config>……</aop:config> </beans>
    • 說明:一個beans標簽中可以配置多個aop:config標簽

    3.2.2)aop:aspect

    • 名稱:aop:aspect
    • 類型:標簽
    • 歸屬:aop:config標簽
    • 作用:設置具體的AOP通知對應的切入點
    • 格式:
    <aop:config><aop:aspect ref="beanId">……</aop:aspect><aop:aspect ref="beanId">……</aop:aspect> </aop:config>
    • 說明:一個aop:config標簽中可以配置多個aop:aspect標簽
    • 基本屬性:ref:通知在的bean的id

    3.2.3)aop:pointcut

    • 名稱:aop:pointcut
    • 類型:標簽
    • 歸屬:aop:config標簽、aop:aspect標簽
    • 作用:設置切入點
    • 格式:
    <aop:config><aop:pointcut id="pointcutId" expression="……"/><aop:aspect><aop:pointcut id="pointcutId" expression="……"/></aop:aspect> </aop:config>
    • 說明:一個aop:config標簽中可以配置多個aop:pointcut標簽,且該標簽可以配置在aop:aspect標簽內
    • 基本屬性:id:識別切入點的名稱。expression:切入點表達式

    3.3)切入點

    • 切入點描述的是某個方法
    • 切入點表達式是一個快速匹配方法描述的統配格式,類似于正則表達式

    3.4)切入點表達式的組成

    • 切入點描述的是某個方法
    • 切入點表達式是一個快速匹配方法描述的統配格式,類似于正則表達式

    關鍵字(訪問修飾符 返回值 包名.類名.方法名(參數)異常名)

    關鍵字:描述表達式的匹配模式(參看關鍵字列表)
    訪問修飾符:方法的訪問孔子權限修飾符
    類名:方法所在的類(此處可以配置接口名稱)
    異常:方法定義中指定拋出的異常

    • 范例:
    execution(public User com.***.service.Uservice.findById(int))

    3.4.1)切入點表達式——關鍵字

    • execution:匹配執行指定的方法
    • args:匹配帶有指定參數類型的方法
    • within:。。。。
    • this:。。。。
    • target:。。。
    • @within:。。。
    • @target:。。。
    • @args:。。。
    • @annotation:。。。
    • bean:。。。
    • reference pointcut:。。。
      目前最多使用的是前兩個后面的不怎么會用

    3.4.2)切入點表達式——通配符

    • *:單個獨立的任意符號,可以獨立出現,也可以作為前綴的匹配符出現

    execution(public * com.包路徑..Uservice.find(*))

    • …:多個連續的任意符號,可以獨立出現,常用于簡化包名與參數的書寫

    execution(public User com…UserService.findById(…))
    匹配com包下的任意包中的UserService類或接口中所有名稱為findById的方法

    • +:專用匹配子類的類型

    execution(* *…Service+.(…))

    3.4.3) 切入點表達式——邏輯運算符

    • &&:連接兩個切入點表達式,表示兩個切入帶你表達式同時成立的匹配
    • ||:連接兩個切入點表達式,表示兩個切入點表達式成立任意的一個匹配
    • !:連接單個切入點表達式,表示該切入點表達式不成立的匹配

    3.4.4)切入點表達式——范例

    execution(* *(..)) execution(* *..*(..)) execution(* *..*.*(..)) execution(public * *..*.*(..)) execution(public int *..*.*(..)) execution(public void *..*.*(..)) execution(public void com..*.*(..)) execution(public void com..service.*.*(..)) execution(public void com.itheima.service.*.*(..)) execution(public void com.itheima.service.User*.*(..)) execution(public void com.itheima.service.*Service.*(..)) execution(public void com.itheima.service.UserService.*(..)) execution(public User com.itheima.service.UserService.find*(..)) execution(public User com.itheima.service.UserService.*Id(..)) execution(public User com.itheima.service.UserService.findById(..)) execution(public User com.itheima.service.UserService.findById(int)) execution(public User com.itheima.service.UserService.findById(int,int)) execution(public User com.itheima.service.UserService.findById(int,*)) execution(public User com.itheima.service.UserService.findById(*,int)) execution(public User com.itheima.service.UserService.findById()) execution(List com.itheima.service.*Service+.findAll(..))

    3.5)切入點的三種配置方式

    <aop:config><aop:pointcut id="pt1" expersion="execution(* *(..))"/><aop:aspcet ref="myAdvice"><!--配置局部切入點--><aop:pointcut id="pt2" expression="execution(* *(..))/"><!--引用公共切入點--><aop:before method="logAdvice" pointcut-ref="pt1"/><!--引用局部切入點--><aop:before nethod="logAdvice" pointcut-ref="pt2"/><!--直接配置切入點--><aop:before method="logAdvice" pointcut="execution(* *(..))"/></aop:aspect> </aop:config>

    3.6)切入點配置經驗

    • 企業開發命名規范嚴格遵循規范文檔進行
    • 先為方法配置局部切如點
    • 再抽取類中公共切入點
    • 最后抽取全局切入點
    • 代碼走查過程中檢測切入點是否存在越界性包含
    • 代碼走查過程中檢測切入點是否存在非包含性進駐
    • 設定AOP執行檢測程序,在單元測試中監控通知被執行次數與預計次數是否匹配
    • 設定完畢的切入點如果發生調整務必進行回歸測試
      (以上規則使用與XML配置格式)

    3.7)通知類型

    AOP的通知類型共5種

    • 前置通知:原始方法執行前執行,如果通知中拋出異常,阻止原始方法運行
      應用:數據校驗

    • 后置通知:原始方法執行后執行,無論原始方法中是否出現異常,都將執行通知
      應用:現場清理

    • 返回后通知:原始方法正常執行完畢并返回結果后執行,如果原始方法中拋出異常,無法執行
      應用:返回值相關數據處理

    • 拋出異常后通知:原始方法拋出異常后執行,如果原始方法沒有拋出異常,無法執行
      應用:對原始方法中出現異常的異常信息進行處理

    • 環繞通知:在原始方法執行前后均有對應執行方法,還可以阻止原始方法的執行
      應用:十分強大,可以做很多事情。這個也時最常用的

    3.7.1)aop:before

    • 名稱:aop:before
    • 類型:標簽
    • 歸屬:aop:aspect標簽
    • 作用:設置前置通知
    • 格式:
    <aop:aspect ref="adviceID"><aop:before method="methodName" pointcut="切入點表達式的ID"/> </aop:aspect>
    • 說明:一個aop:aspect標簽中可以配置多個aop:before標簽
    • 基本屬性:
      • method:在通知類中設置的當前通知類別對應的方法
      • pointcut:設置當前通知對應的切入點表達式,與pointcut-ref屬性沖突
      • pointcut-ref:設置當前通知對應的切入點id,與pointcut屬性沖突

    3.7.2)aop:after

    • 名稱:aop:after
    • 類型:標簽
    • 歸屬:aop:aspect標簽
    • 作用:設置前置通知
    • 格式
    <aop:aspect ref="adviceId"><aop:after method="methodName" pointcut="切入點表達式Id"/> </aop:aspect>
    • 說明:一個aop:aspect標簽中可以配置多個aop:after標簽
    • 基本屬性:
      • method:在通知類中設置當前通知類別對應的方法
      • pointcut:設置當前通知對應的切入點表達式,與pointcut-ref屬性沖突
      • pointcut-ref:設置當前通知對應的切入點id,與pointcut屬性沖突

    3.7.3)aop:after-returning

    • 名稱:aop:after-returning
    • 類型:標簽
    • 歸屬:aop:aspcet標簽
    • 作用:設置返回后通知
    • 格式:
    <aop:aspect ref="adviceId"><aop:after-returning method="methodName" pointcut="切入點表達式Id"/> </aop:aspect>
    • 說明:一個aop:aspect標簽中可以配置多個aop:after-returning標簽
    • 基本屬性:
      • method:在通知類中設置當前通知類別對應的方法
      • pointcut:設置當前通知對應的切入點表達式,與pointcut-ref屬性沖突
      • pointcut-ref:設置當前通知對應的切入點id,與pointcut屬性沖突

    3.7.4)aop:after-throwing

    • 名稱:aop:after-throwing
    • 類型:標簽
    • 歸屬:aop:aspect標簽
    • 格式:
    <aop:aspect ref="adviceId"><aop:after-throwing method="methodName" pointcut="切入點表達式Id"/> </aop:aspect>
    • 說明:一個aop:aspect標簽中可以配置多個aop:after-throwing
    • 基本屬性:
      • method:在通知類設置當前類別對應的方法
      • pointcut:設置當前通知對應的切入點表達式,與pointcut-ref屬性沖突
      • pointcut-ref:設置當前通知對應的切入點id,與pointcut屬性沖突

    3.7.5)aop:around

    • 名稱:aop:around
    • 類型:標簽
    • 歸屬:aop:aspect標簽
    • 作用:設置環繞通知
    • 格式:
    <aop:around ref="adviceId"><aop:around method="methodName" pointcut="切入點表達式Id"/> </aop:around>
    • 說明:一個aop:aspect標簽中可以配置多個aop:around
    • 基本屬性:
      • method:在通知類中設置當前通知類別對應方法
      • pointcut:設置當前通知對應的切入點表達式,與pointcut-ref屬性沖突
      • pointcut-ref:設置當前通知對應的切入點id,與pointcut屬性沖突
        環繞通知的開發方式:
      • 環繞通知實在原始方法前后天機功能,在環繞通知中,存在對原始方法的顯示調用
      public Object around(ProceedingJoinPoint pjp)throws Throwable{Object ret =pjp.proceed();return ret;

    }
    ```

    • 環繞通知方法相關說明:
      • 方法必須設定發Object類型的返回值,否則會攔截原始方法的返回。如果原始方法返回值類型為void,通知方法返回值也可以設定返回值類型為void,最終反回null
      • 方法需要在第一個參數為設定ProceedjionPoint對象,通過該對象調用Proceed()方法,實現對原始方法的調用。如省略該參數,原始方法將無法執行。
      • 使用Proceed()方法調用原始方法時,因無法預知原始方法運行過程是否回出現異常,強制拋出Throwable對象,封裝原始方法中肯能會出現的異常信息

    3.8)通知順序

    當同一個切入點配置了多個通知時,通知會村子運行的先后順序,該順序時以通知配置的順序為準

    3.9)通知獲取順序

    • 參數
    • 返回值
    • 異常

    3.9.1)通知獲取參數數據

    第一種情況:

    • 設定通知方法第一個參數為joinPoint,通過該對象調用getArgs()方法,獲取原始方法運行的參數數組
    public void before(JoinPoint jp)throws Throwable{Object[] args=jp.getArgs(); }
    • 所有的通知均可以獲取參數
      第二種情況:
      • 設定通知方法為通知方法傳遞參數(鎖定通知變量名)
      • 原始方法
    public void save(int param1,int param2){System.out.println("user servcer running..."); }
    • AOP配置
    <aop:aspect ref="myAdvice"><aop:pointcut id="pt" expection="expection(* *(..))&amp;&amp;args(a,b)/"><aop:before method="before" pointcut-ref="pt"/> </aop:aspect>
    • 通知類
    public void before(int a,int b){System.out.println("a="+a);System.out.println("b="+b); }

    第三種情況

    • 設定切入點表達式為通知方法傳遞參數(改變通知變量名的定義順序)
    • 原始方法
    public void save(int param1, int param2){System.out.println("user service running..."); }
    • AOP配置
    <aop:aspect ref=myAdvice><aop:pointcut id="pt" expression="exection(* *(..))&amp;&amp;args(a,b)"/><aop:before pointcut-ref="pt" arg-names="b,a"/>當改變此處ab的順序通知類的順序也會改變,建議實踐即可知道 </aopo:aspect>
    • 通知類
    public void before(int a,int b){//傳入此處的順序是照aop種配置的順序決定的System.out.println("a"+a);System.out.println("b"+b); }

    3.9.2)通知獲取返回值數據

    第一種:返回值變量名

    • 設定返回值變量名
    • 原始方法
    public int save(){System.out.println("user service running...");return 100; }
    • AOP配置
    <aop:aspect ref="myAdivce"><aop:pointcut id="pt3" expession="execution(* *(..))"/><aop:after-returning method="afterRtrurning" pointcut-ref="pt3" returniing="ret"/> </aop:aspcet>
    • 通知類
    public void afterReturning(Object ret){System.out.println(ret); }
    • 使用于返回后通知(after-returening)

    第二種:

    • 在通知類的方法種調用原始方法獲取返回值
    • 原始方式
    public int save(){System.out.println("user service runing ...");return 100; }
    • AOP配置
    <aop:aspect ref="myAdvice"><aop:pointcut id="pt2" expression="execution(* *(..)) "/><aop:around method="around" pointcut-ref="pt2" /> </aop:aspect>
    • 通知類
    public Object around(ProceedingJoinPoint pjp) throws Throwable {Object ret = pjp.proceed();return ret; }
    • 適用于環繞通知(around)

    3.9.3)通知獲取異常數據

    第一種:通知類的方法中調用原始方法捕獲異常

    • 在通知類的方法中調用原始方法捕獲異常
    • 原始方式
    public void save{System.out.println("user service running...");int i=1/0; }
    • AOP配置
    <aop:aspect ref="myAdvice"><aop:pointcut id="pt4" expression="execution(* *(..)) "/><aop:around method="around" pointcut-ref="pt4" /> </aop:aspect>
    • 通知類
    public Object around(ProceedingJoinPoint pjp) throws Throwable {Object ret = pjp.proceed(); //對此處調用進行try……catch……捕獲異常,或拋出異常return ret; }

    代碼如下(示例):

    data = pd.read_csv('https://labfile.oss.aliyuncs.com/courses/1283/adult.data.csv') print(data.head())
    • 適用于環繞通知
      第二種:
    • 設定異常對象變量名
    • 原始方法
    public void save(){System.out.println("user service running ...");int i=1/0; }
    • AOP配置
    <aop:aspect ref="myAdvice"><aop:pointcut id="pt4" expression="execution(* *(..)) "/><aop:after-throwing method="afterThrowing" pointcut-ref="pt4" throwing="t"/> </aop:aspect>
    • 通知類
    public void afterThrowing(Throwable t){System.out.println(t.getMessage()); }

    使用于返回后通知(after-throwing)

    4)AOP配置(注解)

    4.1)注解開發AOP制作步驟

    在XML格式基礎上

    • 導入坐標(伴隨spring-context坐標導入已經依賴導入完成)
    • 開啟AOP注解支持
    • 配置切面@Aspect
    • 定義專用的切入點方法,并配置切入帶你@Pointcut
    • 為通知方法配置通知類型以及對應切入點@Before

    4.2)注解開發AOP注意事項

    • 切入點最終體現為一個方法,為參數返回值,無實際方法體內容,但不能是抽象方法
    • 引用切入點時必須使用方法調用名稱,方法后面的()不能省略
    • 切面類中定義的切入點只能在當前類中使用,如果性引用其他類中定義的切入點使用類名.方法名()引用
    • 可以在通知類型注解后添加參數,實現XML配置中的屬性,例如after-rerturning后的returning屬性
    @AfterReturning(value="pt()",returning="ret"){ public void afterReturning(Object ret){System.out.println("before");} } <aop:aspert ref="myAdvice"><aop:pointcut id="pt3" expression="execution(* *(..))"/><aop:after-returning method="afterReturning" point-ref="pt3" returning="ret"/> </aop:aspect>

    4.3)AOP注解詳解

    4.3.1)@Aspect

    • 名稱:@Aspect
    • 類型:注解
    • 作用:設置當前類為切面類
    • 格式
    @Aspect public class AopAdvice {}
    • 說明:一個beans標簽中可以配置多個aop:config

    4.3.2)@pointcut

    • 名稱:@pointcut
    • 類型:注解
    • 作用:使用當前方法名作為切入點引用名稱
    • 格式:
    @Pointcut("execution(* *(..))") public void pt() {}
    • 說明:被修飾分方法忽略其他業務功能,格式設定為無參返回值的方法,方法體內空實現(非抽象)

    4.3.3) @Before

    • 名稱:@Before
    • 類型:注解
    • 作用:標注當前方法作為前置通知
    • 格式:
    @Before("pt()") public void before(){}

    4.3.4)@After

    • 名稱:@After
    • 類型:注解
    • 作用:標注當前方法作為后置通知
    • 格式:
    @After("pt()") public void after(){}

    4.3.5)@AfterRuterning

    • 名稱:@@AfterRuterning
    • 類型:注解
    • 作用:標注當前方法作為返回后通知
    • 格式
    @AfterReturning(value="pt()",returning = "ret") public void afterReturning(Object ret) {}
    • 特殊參數:returning:設定使用通知方法參數接收返回值的變量名

    4.3.6)@AfterThrowing

    • 名稱:@AfterThrowing
    • 類型:注解
    • 作用:標注當前方法作為異常后通知
    • 格式:
    @AfterThrowing(value="pt()",throwing = "t") public void afterThrowing(Throwable t){}
    • 特殊參數:throwing:設定使用通知方法參數接收原始方法中拋出的異常對象名

    4.3.7)@Around

    • 名稱:@Around
    • 類型:注解
    • 作用:標注當前方法作為環繞通知
    • 格式:
    @Around("pt()") public Object around(ProceedingJoinPoint pjp) throws Throwable {Object ret = pjp.proceed();return ret; }

    4.4)AOP注解開發通知執行順序控制

  • AOP使用XML配置情況下,通知的執行順序由破欸之順序決定,在注解情況下由不存在配置順序概念,參照通知所配置的方法名字符串對應的編碼值順序,可以簡單理解為字母排序

    - 同一個通知類中,相同通知類型以方法名排序為準- 不同通知類中,以類名排序為準- 使用@Order注解通過變更bean的加載順序改變通知的加載順序
  • 企業開發經驗

    2.1) 通知方法名由3部分組成,分別時前綴、順序編碼、功能描述
    2.2) 前綴位固定字符串,例如baidu等無實際意義
    2.3) 順序編碼位6位以內的整數,通常3位即可,不足位補0
    2.4) 功能描述為該方法對應的實際通知功能,例如exception、strLenCheck

    - 制作通知執行順序使用順序編碼控制,使用時做一定的預留- 003使用,006使用,預留001、002、004、005、007、008- 使用時從中段開始使用,方便后期做前置追加或后置追加- 最終順序以運行順序為準,以測試結果為準,不以設定規則為準
  • 4.5)AOP 注解驅動

    • 名稱:@EnableAspectJAutoProxy
    • 類型:注解
    • 作用:設置當前類開啟AOP注解驅動的支持,加載AOP注解
    • 格式:
    @Configuration@ComponentScan("com.itheima")@EnableAspectJAutoProxypublic class SpringConfig {}

    5)AOP底層原理

    • 靜態代理
    • 動態代理——proxy
    • 動態代理——CGLIB
    • 織入形式

    5.1)靜態代理

    裝飾著模式(Decorator Pattern):在不驚動原始設計的基礎上,為其添加功能

    public class UserServiceDecorator implements UserService{private UserService userService;public UserServiceDecorator(UserService userService) {this.userService = userService;}public void save() {//原始調用userService.save();//增強功能(后置)System.out.println("增強");} }

    5.2)動態代理——JDK Proxy

    JDKProxy動態代理時針對于對象做代理,要求原始對象具有接口實現,并對接口方法進行增強

    public class UserServiceJDKProxy {public UserService createUserServiceJDKProxy(final UserService userService){//獲取被代理對象的類加載器ClassLoader classLoader = userService.getClass().getClassLoader();//獲取被代理對象實現的接口Class[] classes = userService.getClass().getInterfaces();//對原始方法執行進行攔截并增強InvocationHandler ih = new InvocationHandler() {public Object invoke(Object proxy, Method method, Object[] args) throws Throwable {//前置增強內容Object ret = method.invoke(userService, args);//后置增強內容System.out.println("增強2");return ret;}};//使用原始被代理對象創建新的代理對象UserService proxy = (UserService) Proxy.newProxyInstance(classLoader,classes,ih);return proxy;} }

    5.3)動態代理CGLIB

    • CGLIB(Code Generation Library),Code生成類庫
    • CGLIB動態代理不限定是否具有接口,可以對任意操作進行增強
    • CGLIB動態代理無需原始被代理對象,動態創建處新的代理對象

    public class UserServiceImplCglibProxy {public static UserServiceImpl createUserServiceCglibProxy(Class clazz){//創建Enhancer對象(可以理解為內存中動態創建了一個類的字節碼)Enhancer enhancer = new Enhancer();//設置Enhancer對象的父類是指定類型UserServerImplenhancer.setSuperclass(clazz);Callback cb = new MethodInterceptor() {public Object intercept(Object o, Method m, Object[] a, MethodProxy mp) throws Throwable {Object ret = mp.invokeSuper(o, a);if(m.getName().equals("save")) {System.out.println("增強");}return ret;}};//設置回調方法enhancer.setCallback(cb);//使用Enhancer對象創建對應的對象return (UserServiceImpl)enhancer.create();} }

    5.4)代理模式的選擇

    Spring可以通過配置的形式控制使用的代理形式,默認使用JDKProxy,通過配置可以修改為CGLIB

    • XML配置
    <!--XMP配置AOP--> <aop:config proxy-target-class="false"></aop:config>
    • XML注解支持
    <!--注解配置AOP--> <aop:aspectj-autoproxy proxy-target-class="false"/>
    • 注解驅動
    //注解驅動 @EnableAspectJAutoProxy(proxyTargetClass = true)

    5.5)織入時機


    總結

    都挺重要的感覺,有需要的話再查查吧

    總結

    以上是生活随笔為你收集整理的SpringDay3的全部內容,希望文章能夠幫你解決所遇到的問題。

    如果覺得生活随笔網站內容還不錯,歡迎將生活随笔推薦給好友。