亚洲乱码中文字幕综合,中国熟女仑乱hd,亚洲精品乱拍国产一区二区三区,一本大道卡一卡二卡三乱码全集资源,又粗又黄又硬又爽的免费视频

Spring AOP詳解面向切面編程思想

 更新時間:2022年06月20日 09:24:14   作者:獨一無二的哈密瓜  
Spring是一個廣泛應(yīng)用的框架,SpringAOP則是Spring提供的一個標(biāo)準(zhǔn)易用的aop框架,依托Spring的IOC容器,提供了極強的AOP擴(kuò)展增強能力,對項目開發(fā)提供了極大地便利

1. 什么是 Spring AOP

AOP (Aspect Oriented Programming): 面向切面編程, 它是一種思想, 它是對某一類事情的集中處理.

例如, 在沒有學(xué)習(xí)AOP之前, 之前的判斷當(dāng)前登錄狀態(tài), 就需要在每一個頁面都實現(xiàn)登錄校驗, 在有了AOP之后, 外面只需在某一處配置以下, 所有的頁面就都可以實現(xiàn)登錄驗證了, 就不需要寫太多重復(fù)的代碼,

Spring AOP, 是一個框架, 提高了一種對 AOP 思想的實現(xiàn).

2. AOP 的組成

2.1 切面 (Aspect)

切面由切點和通知組成, 它既包含了橫切邏輯的定義, 也包括了連接點的定義.

切面是包含了: 通知, 切點和切面的類, 相當(dāng)于 AOP 實現(xiàn)的某個功能的集合

2.2 切點 (Pointcur)

切點的作用就是提供一組規(guī)則 (使用 AspectJ pointcut expression language 來描述) 來匹配 連接點, 給滿足規(guī)則的 連接點添加 Advice

切點相當(dāng)于保存了眾多連接點的一個集合

2.3 連接點 (Join Point)

應(yīng)用執(zhí)行過程中能夠插入切面的一個點, 這個點可以是方法的調(diào)用時, 拋出異常時, 甚至修改字段時. 切面代碼可以利用這些點插入到應(yīng)用的正常流程之中, 并添加新的行為.

連接點相當(dāng)于需要被增強的某個 AOP 功能的所有方法.

2.4 通知 (Advice)

定義了切面是什么, 何時使用, 其描述切面要完成的工作, 還解決何時執(zhí)行這個工作的問題,

Spring切面類中, 可以在方法上使用以下注解, 會設(shè)置方法為通知方法, 在滿足條件后會通知本方法進(jìn)行調(diào)用.

?法進(jìn)?調(diào)用:

前置通知使用 @Before:通知方法會在目標(biāo)方法調(diào)用之前執(zhí)行.

后置通知使用 @After:通知方法會在目標(biāo)方法返回或者拋出異常后調(diào)用.

返回之后通知使用 @AfterReturning:通知方法會在目標(biāo)方法返回后調(diào)用.

拋異常后通知使用 @AfterThrowing:通知方法會在目標(biāo)方法拋出異常后調(diào)用.

環(huán)繞通知使用 @Around:通知包裹了被通知的方法, 在被通知的方法通知之前和調(diào)用之后執(zhí)行自定義的行為.

3. Spring AOP 的使用

3.1 添加 AOP 框架

在 pom.xml 中添加依賴

<!-- https://mvnrepository.com/artifact/org.springframework.boot/springboot-starter-aop -->
		<dependency>
			<groupId>org.springframework.boot</groupId>
			<artifactId>spring-boot-starter-aop</artifactId>
		</dependency>

3.2 定義切面和切點

@Aspect // 定義切面
@Component
public class UserAspect {
    // 切點 (配置攔截規(guī)則)
    @Pointcut("execution(* com.example.demo.controller.UserController.*)")
    public void pointcut() {
        // 這是一個空方法, 不需要有具體的實現(xiàn)
    }
}

切點表達(dá)式注意事項

AspectJ 支持三種通配符

  • * : 匹配任意字符, 只匹配一個元素 (包, 類, 方法, 方法參數(shù))
  • .. : 匹配任意字符,可以匹配多個元素, 在標(biāo)識類時, 必須聯(lián)合 * 使用
  • + : 表示按類型匹配指定類和所有類, 必須跟在類名后面, 如 com.cad.Car+, 表示繼承該類的所有子類包括本身

execution() 是最常用的切點函數(shù)

語法為: execution(<修飾符> <返回類型> <包.類.方法(參數(shù))> <異常>) (注意: 修飾符和異常可以省略)

示例:

  • execution(* com.cad.demo.User.*(..)) :匹配 User 類?的所有?法。
  • execution(* com.cad.demo.User+.*(..)) :匹配該類的?類包括該類的所有?法。
  • execution(* com.cad.*.*(..)) :匹配 com.cad 包下的所有類的所有?法。
  • execution(* com.cad..*.*(..)) :匹配 com.cad 包下、?孫包下所有類的所有?法。
  • execution(* addUser(String, int)) :匹配 addUser ?法,且第?個參數(shù)類型是 String,第?個參數(shù)類型是 int。

3.3 定義通知 (五種)

@Aspect // 定義切面
@Component
public class UserAspect {
    // 切點 (配置攔截規(guī)則)
    @Pointcut("execution(* com.example.demo.controller.UserController.*(..))")
    public void pointcut() {
        // 這是一個空方法, 不需要有具體的實現(xiàn)
    }
    @Before("pointcut()")
    public void doBefore(){
        System.out.println("執(zhí)行 Before 方法");
    }
    @After("pointcut()")
    public void doAfter(){
        System.out.println("執(zhí)行 After 方法");
    }
    @AfterReturning("pointcut()")
    public void doAfterReturning() {
        System.out.println("執(zhí)行 AfterReturning 方法");
    }
    @AfterThrowing("pointcut()")
    public void doAfterThrowing() {
        System.out.println("執(zhí)行 AfterThrowing 方法");
    }
    @Around("pointcut()")
    public Object doAround(ProceedingJoinPoint joinPoint) {
        Object object = null;
        System.out.println("Around 方法開始執(zhí)行");
        try {
            // 執(zhí)行攔截方法
            object = joinPoint.proceed();
        } catch (Throwable throwable) {
            throwable.printStackTrace();
        }
        System.out.println("Around 方法結(jié)束執(zhí)行");
        return object;
    }
}

正常時

拋出異常時

4. Spring AOP 實現(xiàn)原理

Spring AOP 是構(gòu)建在動態(tài)代理基礎(chǔ)上, 因此 Spring 對 AOP 的支持局限于方法級別的攔截.

Spring AOP 是基于動態(tài)代理實現(xiàn)的.

動態(tài)代理分為兩類:

  • JDK Proxy(JDK 動態(tài)代理機(jī)制)
  • CGLIB 動態(tài)代理

默認(rèn)情況下, 實現(xiàn)了接口的類, 使用 AOP 會基于 JDK 生成代理類, 沒有實現(xiàn)接口的類, 會基于 CGLIB 生成代理類

4.1 織入 (Weaving)

代理的生成時機(jī)

織?是把切面應(yīng)用到目標(biāo)對象并創(chuàng)建新的代理對象的過程,切面在指定的連接點被織?到目標(biāo)對象中。

在目標(biāo)對象的?命周期里有多個點可以進(jìn)?織入:

  • 編譯期:切面在目標(biāo)類編譯時被織?。這種?式需要特殊的編譯器。AspectJ的織?編譯器就是以這種方式織入切?的。
  • 類加載器:切?在目標(biāo)類加載到JVM時被織入。這種方式需要特殊的類加載器(ClassLoader),它可以在目標(biāo)類被引入應(yīng)用之前增強該目標(biāo)類的字節(jié)碼。AspectJ5的加載時織入(load-time weaving. LTW)就支持以這種方式織入切面。
  • 運行期:切面在應(yīng)用運行的某?時刻被織入。?般情況下,在織入切面時,AOP容器會為目標(biāo)對象動態(tài)創(chuàng)建一個代理對象. Spring AOP 就是以這種方式織入切面的

4.2 JDK 和 CGLIB 實現(xiàn)的區(qū)別

  • JDK 實現(xiàn)要求被代理類必須實現(xiàn)接口, 之后是通過 InvocationHandlerProxy, 在運行時動態(tài)的在內(nèi)存中生成了代理類對象, 該代理對象是通過實現(xiàn)同樣的接口實現(xiàn) (類似靜態(tài)代理接口實現(xiàn)的方式), 只是該代理類是在運行期時,動態(tài)的織入統(tǒng)一的業(yè)務(wù)邏輯字節(jié)碼來完成.
  • CGLIB 實現(xiàn), 被代理類可以不實現(xiàn)接口, 是通過繼承被代理類, 在運行時動態(tài)的生成代理類對象.

到此這篇關(guān)于Spring AOP詳解面向切面編程思想的文章就介紹到這了,更多相關(guān)Spring AOP切面編程內(nèi)容請搜索腳本之家以前的文章或繼續(xù)瀏覽下面的相關(guān)文章希望大家以后多多支持腳本之家!

相關(guān)文章

  • BeanDefinition基礎(chǔ)信息講解

    BeanDefinition基礎(chǔ)信息講解

    今天小編就為大家分享一篇關(guān)于BeanDefinition基礎(chǔ)信息講解,小編覺得內(nèi)容挺不錯的,現(xiàn)在分享給大家,具有很好的參考價值,需要的朋友一起跟隨小編來看看吧
    2019-02-02
  • Java實現(xiàn)獲取某年某月第一天/最后一天的方法

    Java實現(xiàn)獲取某年某月第一天/最后一天的方法

    這篇文章主要介紹了Java實現(xiàn)獲取某年某月第一天/最后一天的方法,涉及java日期運算相關(guān)操作技巧,需要的朋友可以參考下
    2018-02-02
  • Java中注解的工作原理

    Java中注解的工作原理

    什么是注解?用一個詞就可以描述注解,那就是元數(shù)據(jù),即一種描述數(shù)據(jù)的數(shù)據(jù),Java中的注解是如何工作的,需要的朋友可以參考下
    2015-12-12
  • Java實現(xiàn)的日歷功能完整示例

    Java實現(xiàn)的日歷功能完整示例

    這篇文章主要介紹了Java實現(xiàn)的日歷功能,結(jié)合完整實例形式分析了Java日歷功能相關(guān)的日期時間獲取、計算、顯示等操作技巧,需要的朋友可以參考下
    2019-02-02
  • 詳解Java中static關(guān)鍵字和內(nèi)部類的使用

    詳解Java中static關(guān)鍵字和內(nèi)部類的使用

    這篇文章主要為大家詳細(xì)介紹了Java中static關(guān)鍵字和內(nèi)部類的使用,文中的示例代碼講解詳細(xì),感興趣的小伙伴可以跟隨小編一起學(xué)習(xí)一下
    2022-08-08
  • java并發(fā)編程之cas詳解

    java并發(fā)編程之cas詳解

    這篇文章主要介紹了java并發(fā)編程之cas詳解,涉及cas使用場景和cas用作原子操作等內(nèi)容,具有一定參考價值,需要的朋友可以了解下。
    2017-11-11
  • Java中SynchronousQueue的底層實現(xiàn)原理剖析

    Java中SynchronousQueue的底層實現(xiàn)原理剖析

    BlockingQueue的實現(xiàn)類中,有一種阻塞隊列比較特殊,就是SynchronousQueue(同步移交隊列),隊列長度為0。本文就來剖析一下SynchronousQueue的底層實現(xiàn)原理,感興趣的可以了解一下
    2022-11-11
  • 詳解SpringBoot如何優(yōu)雅的進(jìn)行全局異常處理

    詳解SpringBoot如何優(yōu)雅的進(jìn)行全局異常處理

    在SpringBoot的開發(fā)中,為了提高程序運行的魯棒性,我們經(jīng)常需要對各種程序異常進(jìn)行處理,但是如果在每個出異常的地方進(jìn)行單獨處理的話,這會引入大量業(yè)務(wù)不相關(guān)的異常處理代碼,這篇文章帶大家了解一下如何優(yōu)雅的進(jìn)行全局異常處理
    2023-07-07
  • 理解 MyBatis 是如何在 Spring 容器中初始化的

    理解 MyBatis 是如何在 Spring 容器中初始化的

    這篇文章主要介紹了理解 MyBatis 是如何在 Spring 容器中初始化的,文中通過示例代碼介紹的非常詳細(xì),對大家的學(xué)習(xí)或者工作具有一定的參考學(xué)習(xí)價值,需要的朋友們下面隨著小編來一起學(xué)習(xí)學(xué)習(xí)吧
    2020-11-11
  • 關(guān)于Java中使用jdbc連接數(shù)據(jù)庫中文出現(xiàn)亂碼的問題

    關(guān)于Java中使用jdbc連接數(shù)據(jù)庫中文出現(xiàn)亂碼的問題

    這篇文章主要介紹了關(guān)于Java中使用jdbc連接數(shù)據(jù)庫中文出現(xiàn)亂碼的問題,默認(rèn)的編碼和數(shù)據(jù)庫表中的數(shù)據(jù)使用的編碼是不一致的,如果是中文,那么在數(shù)據(jù)庫中執(zhí)行時已經(jīng)是亂碼了,需要的朋友可以參考下
    2023-04-04

最新評論