国产亚洲精品福利在线无卡一,国产精久久一区二区三区,亚洲精品无码国模,精品久久久久久无码专区不卡

當(dāng)前位置: 首頁 > news >正文

湖南建設(shè)人力資源官方網(wǎng)站萬能軟文模板

湖南建設(shè)人力資源官方網(wǎng)站,萬能軟文模板,寧慈建設(shè)網(wǎng)站,電子商務(wù)網(wǎng)站創(chuàng)建方案??前面的話?? 本篇文章將介紹一種特別重要的思想,AOP(Aspect Oriented Programming),即面向切面編程,可以說是OOP(Object Oriented Programming,面向?qū)ο缶幊?amp;#xff09;的補(bǔ)充和完善。 …

??前面的話??

本篇文章將介紹一種特別重要的思想,AOP(Aspect Oriented Programming),即面向切面編程,可以說是OOP(Object Oriented Programming,面向?qū)ο缶幊?#xff09;的補(bǔ)充和完善。

AOP把軟件系統(tǒng)分為兩個部分:核心關(guān)注點(diǎn)橫切關(guān)注點(diǎn)。業(yè)務(wù)處理的主要流程是核心關(guān)注點(diǎn),與之關(guān)系不大的部分是橫切關(guān)注點(diǎn)。

📒博客主頁:未見花聞的博客主頁
🎉歡迎關(guān)注🔎點(diǎn)贊👍收藏??留言📝
📌本文由未見花聞原創(chuàng),CSDN首發(fā)!
📆首發(fā)時間:🌴2022年9月6日🌴
📆修改時間:🌴2023年4月11日🌴
??堅持和努力一定能換來詩與遠(yuǎn)方!
💭推薦書籍:📚《Spring實(shí)戰(zhàn)》,📚《SpringBoot實(shí)戰(zhàn)》
💬參考在線編程網(wǎng)站:🌐??途W(wǎng)🌐力扣
博主的碼云gitee,平常博主寫的程序代碼都在里面。
博主的github,平常博主寫的程序代碼都在里面。
🍭作者水平很有限,如果發(fā)現(xiàn)錯誤,一定要及時告知作者哦!感謝感謝!


📌導(dǎo)航小助手📌

  • 1.面向切面編程AOP
    • 1.1什么是AOP?
    • 1.2AOP的作用
    • 1.3AOP的核心概念
  • 2.Spring AOP
    • 2.1Spring AOP的使用
    • 2.2AspectJ表達(dá)式基本語法
    • 2.3拋出異常后通知與環(huán)繞通知
    • 2.4Spring AOP的實(shí)現(xiàn)原理


封面區(qū)


1.面向切面編程AOP

1.1什么是AOP?

AOP(Aspect Oriented Programming),即面向切面編程,可以說是OOP(Object Oriented Programming,面向?qū)ο缶幊?#xff09;的補(bǔ)充和完善。OOP引入封裝、繼承、多態(tài)等概念來建立一種對象層次結(jié)構(gòu),用于模擬公共行為的一個集合。不過OOP允許開發(fā)者定義縱向的關(guān)系,但并不適合定義橫向的關(guān)系,例如日志功能。日志代碼往往橫向地散布在所有對象層次中,而與它對應(yīng)的對象的核心功能毫無關(guān)系對于其他類型的代碼,如安全性、異常處理和透明的持續(xù)性也都是如此,這種散布在各處的無關(guān)的代碼被稱為橫切(cross cutting),在OOP設(shè)計中,它導(dǎo)致了大量代碼的重復(fù),而不利于各個模塊的重用。

AOP技術(shù)恰恰相反,它利用一種稱為"橫切"的技術(shù),剖解開封裝的對象內(nèi)部,并將那些影響了多個類的公共行為封裝到一個可重用模塊,并將其命名為"Aspect",即切面。所謂"切面",簡單說就是那些與業(yè)務(wù)無關(guān),卻為業(yè)務(wù)模塊所共同調(diào)用的邏輯或責(zé)任封裝起來,便于減少系統(tǒng)的重復(fù)代碼,降低模塊之間的耦合度,并有利于未來的可操作性和可維護(hù)性。

使用"橫切"技術(shù),AOP把軟件系統(tǒng)分為兩個部分:核心關(guān)注點(diǎn)橫切關(guān)注點(diǎn)。業(yè)務(wù)處理的主要流程是核心關(guān)注點(diǎn),與之關(guān)系不大的部分是橫切關(guān)注點(diǎn)。橫切關(guān)注點(diǎn)的一個特點(diǎn)是,他們經(jīng)常發(fā)生在核心關(guān)注點(diǎn)的多處,而各處基本相似,比如權(quán)限認(rèn)證、日志、事物。AOP的作用在于分離系統(tǒng)中的各種關(guān)注點(diǎn),將核心關(guān)注點(diǎn)和橫切關(guān)注點(diǎn)分離開來。

1.2AOP的作用

想象一個場景,我們在做后臺系統(tǒng)時,除了登錄和注冊等幾個功能不需要做用戶登錄驗(yàn)證之外,其他幾乎所有頁面都需要先驗(yàn)證用戶登錄的狀態(tài),那這個時候我們要怎么處理呢?

如果不使用AOP,我們就需要在每一個Controller層都寫一遍驗(yàn)證用戶是否已經(jīng)登錄的程序,如果你實(shí)現(xiàn)的功能有很多,并且這些功能都需要進(jìn)行登錄驗(yàn)證,那你就需要編寫大量重復(fù)的代碼,非常的麻煩,盡管你可以將登錄驗(yàn)證實(shí)現(xiàn)的邏輯封裝在一個方法中,但是你要在很多地方調(diào)用這個方法,還是很麻煩。

如果使用AOP,在進(jìn)入核心的業(yè)務(wù)代碼之前會做統(tǒng)一的一個攔截,去驗(yàn)證用戶是否登錄,這樣就很方便,僅需做一個攔截工作,再將驗(yàn)證代碼一執(zhí)行即可。

除了登錄驗(yàn)證功能之外,還有很多功能也可以使用AOP,比如:

  • 統(tǒng)一日志記錄與持久化。
  • 統(tǒng)一方法執(zhí)行時間統(tǒng)計。
  • 統(tǒng)一數(shù)據(jù)返回格式。
  • 統(tǒng)一處理程序中的異常。
  • 統(tǒng)一事務(wù)的開啟與提交。

也就是說使用 AOP 可以擴(kuò)充多個對象的某個能力,所以 AOP 可以說是 OOP (Object Oriented Programming,面向?qū)ο缶幊?#xff09;的補(bǔ)充和完善。

1.3AOP的核心概念

1、橫切關(guān)注點(diǎn)

想要對哪些方法或類進(jìn)行攔截,攔截后怎么處理,這些關(guān)注點(diǎn)稱之為橫切關(guān)注點(diǎn)。

2、切面(aspect)

類是對物體特征的抽象,切面就是對橫切關(guān)注點(diǎn)的抽象,你可以認(rèn)為切面相當(dāng)于橫切關(guān)注點(diǎn)。

3、連接點(diǎn)(joinpoint)

被攔截到的點(diǎn),因?yàn)镾pring只支持方法類型的連接點(diǎn),所以在Spring中連接點(diǎn)指的就是被攔截到的方法,實(shí)際上連接點(diǎn)還可以是字段或者構(gòu)造器。

4、切入點(diǎn)(pointcut)

提供一組規(guī)則,根據(jù)規(guī)則匹配合法的連接點(diǎn),滿足規(guī)則的連接點(diǎn)可以理解為切點(diǎn),然后可以為切點(diǎn)提供具體的處理(通知)。

5、通知(advice)

所謂通知指的就是指攔截到連接點(diǎn)之后要執(zhí)行的代碼,或者說在切點(diǎn)出所需要執(zhí)行的代碼是什么。

通知包含前置通知,后置通知,返回之后通知,拋異常后通知與環(huán)繞通知五類。

在Spring切面類中,可以在方法上使用以下注解,會設(shè)置方法為通知方法,在滿足條件后會調(diào)用對應(yīng)滿足條件的方法:

  • 前置通知使用@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í)行自定義的行為。

1

6、目標(biāo)對象

代理的目標(biāo)對象。

7、織入(weaving)

織入(weaving)即代理的生成時機(jī),
織入是把切面應(yīng)用到目標(biāo)對象并創(chuàng)建新的代理對象的過程,切面在指定的連接點(diǎn)被織入到目標(biāo)對象中。
在目標(biāo)對象的生命周期里有多個點(diǎn)可以進(jìn)行織入∶

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

8、引入(introduction)

在不修改代碼的前提下,引入可以在運(yùn)行期為類動態(tài)地添加一些方法或字段。

2.Spring AOP

面向切面編程是一種思想,Spring AOP是AOP的一種實(shí)現(xiàn)。

2.1Spring AOP的使用

SpringAOP使用的主要步驟為:
第一步,在SpringBoot項目中添加AOP相關(guān)的依賴。
第二步,定義切面。
第三步,定義切點(diǎn)。
第四步,實(shí)現(xiàn)通知。

第一步,在SpringBoot項目中添加AOP相關(guān)的依賴,就是在Maven的配置文件中添加aop的依賴。
由于使用Edit Starters插件訪問官方的源是找不到有關(guān)SpringBoot的AOP依賴,這是因?yàn)樵趇dea中,上面只列舉了一些常用的依賴,不是所有依賴都在上面,如果找不到我們就去Maven中央倉庫中去尋找。

搜索一下,找到這個依賴,然后進(jìn)去復(fù)制依賴信息拷貝到Maven的配置文件中就行。
2

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

第二步,定義切面,在spring boot項目中其實(shí)就是加上@Aspect和@Component注解的一個類,這個類就表示一個切面。

//設(shè)置切面,這個類就是一個切面
@Aspect
@Component
public class UserAspect {...
}

第三步,在切面里面定義切點(diǎn),在Spring中其實(shí)本質(zhì)上就是一個方法,具體說是使用 @Pointcut注解修飾的一個方法,該方法不需要配置任何信息。

    //定義切點(diǎn),設(shè)置攔截規(guī)則@Pointcut("execution(* com.example.demo.controller.UserController.* (..))")public void pointcut() {}

其中@Pointcut注解中的參數(shù)是一個AspectJ表達(dá)式,它的作用就是設(shè)置哪些返回值類型哪些類的哪些方法需要攔截可以指定到參數(shù)列表。
4

第四步,實(shí)現(xiàn)通知,本質(zhì)上就是實(shí)現(xiàn)一個方法,只不過在方法上加上不同通知類型的注解即可,如前置通知加上@Before注解,注解的參數(shù)為切點(diǎn)方法名。

    //前置通知@Before("pointcut()")public void doBefore() {System.out.println("執(zhí)行Before通知");}

同理,后置通知也是如此,就是將注解改為@After:

    //后置通知@After("pointcut()")public void doAfter() {System.out.println("執(zhí)行After通知");}

以及目標(biāo)方法返回后通知@AfterReturning:

    //返回之后通知@AfterReturning("pointcut()")public void doAfterRunning() {System.out.println("執(zhí)行AfterRunning通知");}

我們來驗(yàn)證一下上述設(shè)置切面攔截代碼的正確性,我們寫一個在攔截范圍的類以及方法:
5
啟動程序,我們訪問頁面http://127.0.0.1:8080/user/hello,看看控制臺的輸出:
6
通過運(yùn)行結(jié)果我們也能夠看出上面三種通知方式執(zhí)行的時機(jī)以及先后順序。

2.2AspectJ表達(dá)式基本語法

*∶匹配任意字符,只匹配一個元素(包,類,或方法,方法參數(shù))
..∶匹配任意字符,可以匹配多個元素,在表示類時,必須和*聯(lián)合使用,匹配參數(shù)列表時表示匹配所有類型的參數(shù)列表。
+ ∶ 表示按照類型匹配指定類及其所有子類,必須跟在類名后面,如com.Car+,表示攔截Cat類以及繼承Cat類的所有子類。

切點(diǎn)表達(dá)式由切點(diǎn)函數(shù)組成,其中execution()是最常用的切點(diǎn)函數(shù),用來匹配方法,語法為∶

execution(<權(quán)限修飾符><返回類型><..方法(參數(shù))><異常>)

其中權(quán)限修飾符與異常項一般省略,返回類型方法以及參數(shù)不可省略,其他項可以省略。

權(quán)限修飾符:

  • 填寫權(quán)限修飾符,就只會匹配相應(yīng)修飾符修飾的方法。
  • 省略,權(quán)限不作為限制,所有權(quán)限修飾符的方法都會匹配。

返回類型,必須參數(shù),不可省略:

  • 填寫具體返回類型,就匹配相應(yīng)返回類型的方法。
  • *表示匹配所有返回值類型的方法。

包,類,一般情況下要有,但是可以省略:

  • 填寫包和類,就只匹配你所規(guī)定的包或類。
  • *表示匹配某目錄下所有的包或者類。
  • +作用在類上,匹配該類以及繼承該類的所有子類。

方法,表示需要匹配方法的名字,參數(shù)表示需要匹配參數(shù)列表的類型,不可省略:

  • 指定方法名和參數(shù)列表,就只匹配你所限定的方法。
  • *可以作用在方法匹配字段上,表示匹配某類中所有的方法。
  • ..可以作用在參數(shù)列表上,對參數(shù)列表類型不做限制。

異常,可以匹配拋出指定異常的方法,該參數(shù)一般省略。

下面來看幾個例子,我們來了解一下AspectJ表達(dá)式:

execution(* com.cad.demo.User.*(..))∶匹配User類里的所有方法。
execution(* com.cad.demo.User+.*(..))∶匹配User類及其子類中的所有方法。
execution(* com.cad.*.*(..))∶匹配com.cad包下的所有類的所有方法。
execution(* com.cad..*.*(..))∶匹配 com.cad 包下、子孫包下所有類的所有方法。
execution(* addUser(String,int))∶ 匹配 addUser 方法,且第一個參數(shù)類型是 String,第二個參數(shù)類型是int。

2.3拋出異常后通知與環(huán)繞通知

前面我們已經(jīng)介紹了前置通知,后者通知以及返回后通知的演示,下面我們繼續(xù)介紹剩下兩種通知,在上面已經(jīng)實(shí)現(xiàn)代碼基礎(chǔ)上,我們繼續(xù)添加通知來進(jìn)行演示。

拋出異常后通知,其實(shí)和前面三種通知的用法可以說一模一樣,只不過只有當(dāng)程序出現(xiàn)異常的時候才會執(zhí)行該通知,寫法如下,就是在切面類中實(shí)現(xiàn)一個方法,使用@AfterThrowing注解修飾即可:

    //拋異常后通知@AfterThrowing("pointcut()")public void doAfterThrowing() {System.out.println("拋出異常后,執(zhí)行AfterThrowing通知");}

然后我們再在目標(biāo)方法中構(gòu)造一個異常,異常隨便寫一個異常就行,如算術(shù)異常:
8

我們訪問頁面http://127.0.0.1:8080/user/world來看一看控制臺輸出:
9
由于出現(xiàn)了異常,方法被強(qiáng)制終止了,沒有返回,所以沒有返回后通知。

最后還剩下一個環(huán)繞通知,環(huán)繞通知你可以理解為將前置通知和后置通知一體化了,環(huán)繞通知最常見的用法之一就是計算目標(biāo)方法執(zhí)行的時間是多少,使用其他通知無法做到,如果使用前置加后置通知進(jìn)行對目標(biāo)方法的計時,在單線程下沒有問題,但是在多線程下有問題,當(dāng)一個線程正在計時時,另外一個線程調(diào)用了前置通知,此時計時開始的時間就被刷新了,那自然計算得到的目標(biāo)方法執(zhí)行時間也就不準(zhǔn)確了,而環(huán)繞通知使一體化的,不存在類似這種線程安全的問題。

環(huán)繞通知相比于其他的三種通知的使用方法較為復(fù)雜,首先實(shí)現(xiàn)環(huán)繞通知的方法必須含有ProceedingJoinPoint類的參數(shù)和使用 @Around注解修飾,表示連接點(diǎn)的執(zhí)行進(jìn)度,方法體里面第一步是執(zhí)行環(huán)繞方法的前置通知,然后通過該類對象獲取目標(biāo)方法執(zhí)行進(jìn)度并調(diào)用,再執(zhí)行環(huán)繞通知的后置通知,最后并返回該目標(biāo)方法進(jìn)度。

    @Around("pointcut()")public Object doAround(ProceedingJoinPoint joinPoint) {Object res = null;System.out.println("執(zhí)行環(huán)繞通知前置通知");try {//根據(jù)連接點(diǎn)進(jìn)度獲取目標(biāo)方法,并執(zhí)行目標(biāo)方法res = joinPoint.proceed();} catch (Throwable e) {e.printStackTrace();}System.out.println("環(huán)繞通知后置通知");return res;}

我們訪問頁面http://127.0.0.1:8080/user/hello來看一看控制臺輸出:
10

我們可以基于環(huán)繞通知實(shí)現(xiàn)對目標(biāo)方法的計時功能:
實(shí)現(xiàn)思路很簡單,就是在執(zhí)行目標(biāo)方法之前開始計時,執(zhí)行完目標(biāo)方法之后結(jié)束計時,差值就是方法運(yùn)行的時間。

計時的方式可以使用時間戳或者spring中的StopWatch類,后者更準(zhǔn)確一點(diǎn),其實(shí)都差不多。

我們可以通過傳入的joinPoint對象獲取目標(biāo)方法的方法名以及具體所在類和包,joinPoint.getSignature().toString()就能生成目標(biāo)方法的全部有關(guān)名字的信息,我們可以加上一個方法的信息來表示哪一個方法執(zhí)行的時間。

    @Around("pointcut()")public Object doTime(ProceedingJoinPoint joinPoint) {Object result = null;//System.out.println("環(huán)繞通知前置通知");String methodName = "";long start = 0;long end = 0;StopWatch stopWatch = new StopWatch();try {//執(zhí)行攔截方法start = System.currentTimeMillis();stopWatch.start();methodName = joinPoint.getSignature().toString();result = joinPoint.proceed();} catch (Throwable throwable) {throwable.printStackTrace();} finally {end = System.currentTimeMillis();stopWatch.stop();}//System.out.println("環(huán)繞通知后置通知");System.out.println(methodName + "執(zhí)行了" + (end - start) + "ms");System.out.println(methodName + "執(zhí)行了" + (stopWatch.getTotalTimeMillis()) + "ms");return result;}

運(yùn)行結(jié)果:
11

2.4Spring AOP的實(shí)現(xiàn)原理

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

Spring AOP支持JDKProxy 和CGLIBProxy方式實(shí)現(xiàn)動態(tài)代理。默認(rèn)情況下,對于非final修飾的類,SpringAOP會基于CGLIBProxy生成代理類,CGLIBProxy生成代理類的原理就是繼承目標(biāo)類,被關(guān)鍵字final修飾的類,由于不能被繼承,所以會基于DKProxy生成代理類。
13
SpringAOP的本質(zhì)就是生成一個目標(biāo)對象的代理類,當(dāng)前端傳來請求時,不會將請求直接交給目標(biāo)對象,而是首先代理類進(jìn)行處理,如果滿足一定的條件,才會將請求交給目標(biāo)對象。

如果處理請求前需要登錄驗(yàn)證,那么代理類會去驗(yàn)證用戶賬戶是否登錄,如果用戶登錄了才會將請求交給目標(biāo)對象并執(zhí)行核心業(yè)務(wù)代碼,否則代理類之間返回響應(yīng)讓用戶先登錄。


參考 & 資料

Spring3:AOP

覺得文章寫得不錯的老鐵們,點(diǎn)贊評論關(guān)注走一波!謝謝啦!

1-99

http://m.aloenet.com.cn/news/34249.html

相關(guān)文章:

  • 廣西做網(wǎng)站口碑營銷方案
  • wordpress去掉導(dǎo)航欄武漢seo關(guān)鍵字推廣
  • 中山專業(yè)制作網(wǎng)站武漢網(wǎng)絡(luò)推廣自然排名
  • 彭陽門戶網(wǎng)站建設(shè)網(wǎng)絡(luò)推廣的方式和途徑有哪些
  • 做網(wǎng)站搞個物理服務(wù)器引流推廣犯法嗎
  • 網(wǎng)站沒有問題但是一直做不上首頁seo托管
  • 網(wǎng)站程序設(shè)計百度鏈接收錄提交入口
  • 學(xué)做效果圖的網(wǎng)站有哪些新手電商運(yùn)營從哪開始學(xué)
  • 網(wǎng)站底部樣式智能建站平臺
  • 網(wǎng)站開發(fā)技術(shù)項目代碼搜索南寧seo外包要求
  • 做網(wǎng)站業(yè)務(wù)員怎么樣為企業(yè)策劃一次網(wǎng)絡(luò)營銷活動
  • 怎么做新網(wǎng)站的推廣下載優(yōu)化大師并安裝
  • 正規(guī)網(wǎng)站建設(shè)官網(wǎng)上海做網(wǎng)絡(luò)口碑優(yōu)化的公司
  • 電商網(wǎng)絡(luò)運(yùn)營浙江搜索引擎優(yōu)化
  • 鄭州企業(yè)網(wǎng)站優(yōu)化哪家便宜2022適合小學(xué)生的簡短新聞
  • 山西網(wǎng)站制作公司百度小說官網(wǎng)
  • 照片做視頻ppt模板下載網(wǎng)站好seo關(guān)鍵詞排名優(yōu)化價格
  • 做電影網(wǎng)站涉及的侵權(quán)問題網(wǎng)盤搜索神器
  • 做釣魚網(wǎng)站要什么工具中企動力做網(wǎng)站推廣靠譜嗎
  • wap網(wǎng)站微信一鍵登錄網(wǎng)絡(luò)營銷案例有哪些
  • 公司網(wǎng)站背景圖百度快速收錄教程
  • 網(wǎng)站建設(shè)明細(xì)報價單凡科網(wǎng)免費(fèi)建站
  • 深圳做網(wǎng)站排名價格百度網(wǎng)盤怎么找片
  • 做ppt一般在什么網(wǎng)站打開網(wǎng)址資料網(wǎng)站
  • 網(wǎng)站后臺登陸地址網(wǎng)站如何推廣
  • 購物網(wǎng)站開發(fā)軟件百度網(wǎng)盤官方網(wǎng)站
  • 每天網(wǎng)站外鏈做幾條最好產(chǎn)品怎么做市場推廣
  • 公司網(wǎng)站服務(wù)器維護(hù)營銷推廣活動方案
  • 網(wǎng)站怎么做導(dǎo)航條手機(jī)百度最新正版下載
  • 網(wǎng)站建設(shè)流程機(jī)構(gòu)互聯(lián)網(wǎng)廣告聯(lián)盟