最新国产好看的视频,伊人天堂AV在线,国产Aaaaaa视频,蜜臀视频在线观看一区,人妻av色图,密臀久久久精品影片,青青视频免费观看毛片,久草在线观看视,国产三级精品色情在线

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

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

1. 什么是 Spring AOP

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

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

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

2. AOP 的組成

2.1 切面 (Aspect)

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

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

2.2 切點(diǎn) (Pointcur)

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

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

2.3 連接點(diǎn) (Join Point)

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

連接點(diǎn)相當(dāng)于需要被增強(qiáng)的某個(gè) AOP 功能的所有方法.

2.4 通知 (Advice)

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

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

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

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

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

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

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

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

3. Spring AOP 的使用

3.1 添加 AOP 框架

在 pom.xml 中添加依賴(lài)

<!-- 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 定義切面和切點(diǎn)

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

切點(diǎn)表達(dá)式注意事項(xiàng)

AspectJ 支持三種通配符

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

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

語(yǔ)法為: execution(<修飾符> <返回類(lèi)型> <包.類(lèi).方法(參數(shù))> <異常>) (注意: 修飾符和異??梢允÷?

示例:

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

3.3 定義通知 (五種)

@Aspect // 定義切面
@Component
public class UserAspect {
    // 切點(diǎn) (配置攔截規(guī)則)
    @Pointcut("execution(* com.example.demo.controller.UserController.*(..))")
    public void pointcut() {
        // 這是一個(gè)空方法, 不需要有具體的實(shí)現(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 方法開(kāi)始執(zhí)行");
        try {
            // 執(zhí)行攔截方法
            object = joinPoint.proceed();
        } catch (Throwable throwable) {
            throwable.printStackTrace();
        }
        System.out.println("Around 方法結(jié)束執(zhí)行");
        return object;
    }
}

正常時(shí)

拋出異常時(shí)

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

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

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

動(dòng)態(tài)代理分為兩類(lèi):

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

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

4.1 織入 (Weaving)

代理的生成時(shí)機(jī)

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

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

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

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

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

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

相關(guān)文章

  • java網(wǎng)上圖書(shū)商城(4)購(gòu)物車(chē)模塊1

    java網(wǎng)上圖書(shū)商城(4)購(gòu)物車(chē)模塊1

    這篇文章主要為大家詳細(xì)介紹了java網(wǎng)上圖書(shū)商城,購(gòu)物車(chē)模塊,具有一定的參考價(jià)值,感興趣的小伙伴們可以參考一下
    2016-12-12
  • Java圖片處理之獲取gif圖一幀圖片的兩種方法

    Java圖片處理之獲取gif圖一幀圖片的兩種方法

    這篇文章主要給大家介紹了關(guān)于Java圖片處理之獲取gif圖一幀圖片的兩種方法,分別是利用Java原生代碼和使用im4java調(diào)用ImageMagick來(lái)實(shí)現(xiàn),兩種方法都給出來(lái)示例代碼供大家參考學(xué)習(xí),需要的朋友們下面來(lái)一起看看吧。
    2017-10-10
  • 詳解java封裝繼承多態(tài)

    詳解java封裝繼承多態(tài)

    這篇文章主要介紹了java封裝繼承多態(tài),文中通過(guò)示例代碼介紹的非常詳細(xì),對(duì)大家的學(xué)習(xí)或者工作具有一定的參考學(xué)習(xí)價(jià)值,需要的朋友們下面隨著小編來(lái)一起學(xué)習(xí)學(xué)習(xí)吧
    2019-03-03
  • Spring中Bean的命名方式代碼詳解

    Spring中Bean的命名方式代碼詳解

    這篇文章主要介紹了Spring中Bean的命名方式代碼詳解,具有一定借鑒價(jià)值,需要的朋友可以參考下
    2018-01-01
  • Spring?Data?Redis切換底層Jedis和Lettuce實(shí)現(xiàn)源碼解析

    Spring?Data?Redis切換底層Jedis和Lettuce實(shí)現(xiàn)源碼解析

    這篇文章主要為大家介紹了Spring?Data?Redis切換底層Jedis和Lettuce實(shí)現(xiàn)方法源碼解析,有需要的朋友可以借鑒參考下,希望能夠有所幫助,祝大家多多進(jìn)步,早日升職加薪
    2023-11-11
  • SpringCache源碼解析Annotation案例講解

    SpringCache源碼解析Annotation案例講解

    這篇文章主要介紹了SpringCache源碼解析Annotation的相關(guān)知識(shí),本文通過(guò)案例講解的非常詳細(xì),感興趣的朋友跟隨小編一起看看吧
    2024-08-08
  • Java AES加密和解密教程

    Java AES加密和解密教程

    這篇文章主要介紹了Java AES加密和解密的相關(guān)資料,幫助大家更好的理解和學(xué)習(xí)Java,感興趣的朋友可以了解下
    2020-12-12
  • java中阻塞隊(duì)列和非阻塞隊(duì)列的實(shí)現(xiàn)

    java中阻塞隊(duì)列和非阻塞隊(duì)列的實(shí)現(xiàn)

    在Java并發(fā)編程中,阻塞隊(duì)列和非阻塞隊(duì)列是兩種主要的隊(duì)列類(lèi)型,分別適用于不同的場(chǎng)景,了解這兩種隊(duì)列的特點(diǎn)和工作機(jī)制,可以幫助開(kāi)發(fā)者更好地選擇合適的數(shù)據(jù)結(jié)構(gòu)解決并發(fā)問(wèn)題
    2024-10-10
  • Java 實(shí)戰(zhàn)項(xiàng)目錘煉之嘟嘟健身房管理系統(tǒng)的實(shí)現(xiàn)流程

    Java 實(shí)戰(zhàn)項(xiàng)目錘煉之嘟嘟健身房管理系統(tǒng)的實(shí)現(xiàn)流程

    讀萬(wàn)卷書(shū)不如行萬(wàn)里路,只學(xué)書(shū)上的理論是遠(yuǎn)遠(yuǎn)不夠的,只有在實(shí)戰(zhàn)中才能獲得能力的提升,本篇文章手把手帶你用java+SSM+jsp+mysql+maven實(shí)現(xiàn)一個(gè)健身房管理系統(tǒng),大家可以在過(guò)程中查缺補(bǔ)漏,提升水平
    2021-11-11
  • SpringBoot整合RabbitMQ及生產(chǎn)全場(chǎng)景高級(jí)特性實(shí)戰(zhàn)

    SpringBoot整合RabbitMQ及生產(chǎn)全場(chǎng)景高級(jí)特性實(shí)戰(zhàn)

    本文主要介紹了SpringBoot整合RabbitMQ及生產(chǎn)全場(chǎng)景高級(jí)特性實(shí)戰(zhàn),文中通過(guò)示例代碼介紹的非常詳細(xì),具有一定的參考價(jià)值,感興趣的小伙伴們可以參考一下
    2021-10-10

最新評(píng)論

阳新县| 道真| 贵阳市| 舞钢市| 加查县| 临沧市| 启东市| 龙山县| 河曲县| 万州区| 锦州市| 淳安县| 天峨县| 定州市| 宜良县| 高阳县| 砀山县| 泾源县| 昔阳县| 临夏县| 清苑县| 城步| 汾西县| 台中县| 泸定县| 如东县| 临夏县| 电白县| 绩溪县| 南郑县| 东光县| 紫阳县| 淮南市| 建水县| 衡山县| 炎陵县| 周宁县| 呼和浩特市| 汝南县| 北川| 讷河市|