中文亚洲精品无码_熟女乱子伦免费_人人超碰人人爱国产_亚洲熟妇女综合网

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

做文學(xué)網(wǎng)站用什么域名口碑營銷怎么做

做文學(xué)網(wǎng)站用什么域名,口碑營銷怎么做,音樂網(wǎng)站建設(shè)程序,百度收錄好最快的網(wǎng)站前言(關(guān)于源碼航行) 在準(zhǔn)備面試和學(xué)習(xí)的過程中,我閱讀了還算多的源碼,比如 JUC、Spring、MyBatis,收獲了很多代碼的設(shè)計(jì)思想,也對平時(shí)調(diào)用的 API 有了更深入的理解;但過多散亂的筆記給我的整理…

前言(關(guān)于源碼航行)
在這里插入圖片描述

在準(zhǔn)備面試和學(xué)習(xí)的過程中,我閱讀了還算多的源碼,比如 JUC、Spring、MyBatis,收獲了很多代碼的設(shè)計(jì)思想,也對平時(shí)調(diào)用的 API 有了更深入的理解;但過多散亂的筆記給我的整理復(fù)習(xí)帶來了比較大的麻煩。
📋 在 C 站零零散散發(fā)了 JUC 的源碼解析和集合源碼解析,收到了很多朋友的喜愛,這里我準(zhǔn)備將一些源碼解析的文章整合起來,為了方便閱讀和歸納在這里整合成目錄:源碼航行閱讀目錄,大家感興趣的話可以關(guān)注一下!
————————————————

第一篇:基礎(chǔ)知識(shí)介紹

這一部分我們來談一下關(guān)于 Spring AOP 的浮在表面上的知識(shí),比如什么是 AOP、它有什么好處、如何使用等等

為什么需要 AOP?

AOP(Aspect Oriented Programming),意為:面向切面編程,通過預(yù)編譯方式和運(yùn)行期動(dòng)態(tài)代理實(shí)現(xiàn)程序功能的統(tǒng)一維護(hù)的一種技術(shù)。AOP是OOP的延續(xù),是軟件開發(fā)中的一個(gè)熱點(diǎn),也是 Spring 框架中的一個(gè)重要內(nèi)容,是函數(shù)式編程的一種衍生范型。

利用AOP可以對業(yè)務(wù)邏輯的各個(gè)部分進(jìn)行隔離,從而使得業(yè)務(wù)邏輯各部分之間的耦合度降低,提高程序的可重用性,同時(shí)提高了開發(fā)的效率。

舉一個(gè)簡單的例子,如果我們想要在每次調(diào)用一個(gè)類中的方法之前輸出一個(gè)日志,那其實(shí)是挺容易實(shí)現(xiàn)的,畫出流程圖就是這個(gè)樣子:
在這里插入圖片描述

那如果我們要在這些方法之前加一個(gè)鑒權(quán)呢?同樣,按照前面的方式,無非就是多 copy 一次嘛

在這里插入圖片描述

就這樣,通過多重 copy 的方式,最終完成了這個(gè)業(yè)務(wù),而這也就代表著,每次擴(kuò)展新的方法,你都要去進(jìn)行 n 次復(fù)制粘貼;每次要更改鑒權(quán)或者日志的邏輯,你都要去進(jìn)行 n 次復(fù)制粘貼;每次。。。。。。

聽起來都讓人非常頭大,但如果我們將邏輯改成這樣呢?

在這里插入圖片描述

我們將這兩個(gè)方法封裝成一個(gè)公共方法,每次在方法之前去調(diào)用這個(gè)公共的方法,不就實(shí)現(xiàn)了可維護(hù)性嗎,這其實(shí)就有一點(diǎn)切面的感覺了。

這樣,我們雖然每次都不用去復(fù)制代碼了,但還是需要在我們需要的位置去調(diào)用這個(gè)接口,而調(diào)用這個(gè)代碼的位置其實(shí)就是 切面。我們用具體的代碼來看一下,下面實(shí)現(xiàn)了一個(gè)統(tǒng)一的接口 BeforeAdvice,然后在每個(gè)方法之前去調(diào)用它。

public interface BeforeAdvice {void before();
}public class LoggingBeforeAdvice implements BeforeAdvice {@Overridepublic void before() {System.out.println("方法調(diào)用之前的日志");}
}public class MyService {private BeforeAdvice beforeAdvice = new LoggingBeforeAdvice();public void myMethodA() {beforeAdvice.before();// 業(yè)務(wù)邏輯System.out.println("執(zhí)行 myMethod1A");}public void myMethodB() {beforeAdvice.before();// 業(yè)務(wù)邏輯System.out.println("執(zhí)行 myMethodB");}
}

到這里,我們就自己實(shí)現(xiàn)了一個(gè)簡單的 AOP;但每次都這樣去創(chuàng)建一個(gè)這樣的類,其實(shí)也是非常復(fù)雜的,這時(shí)候我們就可以借助 Spring AOP 的力量,它幫我們實(shí)現(xiàn)了簡單、直觀、極其易于配置的切面編程方式。

AOP 概念辨析

在正式講解如何使用 Spring AOP 之前,我們來講點(diǎn)無聊的內(nèi)容,關(guān)于 AOP 的概念辨析;這部分內(nèi)容是一些術(shù)語,但是如果能理解它們,就會(huì)對 AOP 整個(gè)流程有較為清晰的把握。

連接點(diǎn)(Join Point):連接點(diǎn)是程序執(zhí)行中的一個(gè)點(diǎn),這個(gè)點(diǎn)可以是方法調(diào)用、方法執(zhí)行、異常拋出等。在 Spring AOP 中,連接點(diǎn)主要是指方法的調(diào)用或執(zhí)行。連接點(diǎn)是通知的實(shí)際應(yīng)用點(diǎn)。

切點(diǎn)(PointCut):由于連接點(diǎn)可能很多(比如一個(gè)類中的所有方法),想要把所有連接點(diǎn)羅列出現(xiàn)顯然有些困難;切點(diǎn)則定義了在應(yīng)用通知的連接點(diǎn)的集合。切點(diǎn)通過切點(diǎn)表達(dá)式(例如:execution(* com.example.service.*.*(..)))來指定匹配的方法和類。切點(diǎn)表達(dá)式用于篩選連接點(diǎn),使得通知只在特定的連接點(diǎn)上執(zhí)行。

通知(Advice):通知是在切點(diǎn)處執(zhí)行的代碼。通知定義了具體的橫切邏輯,決定了在方法執(zhí)行的什么階段(之前、之后、環(huán)繞等)插入橫切邏輯。通知有五種類型,我們會(huì)在下一部分進(jìn)行詳細(xì)的了解;通知就是在 何時(shí) 執(zhí)行 怎樣 的邏輯。

切面(Aspect):切面是 AOP 的核心模塊,它封裝了跨越多個(gè)類的關(guān)注點(diǎn),例如日志記錄、事務(wù)管理或安全控制。切面通過通知(Advice)和切點(diǎn)(Pointcut)來定義在何時(shí)、何地應(yīng)用這些關(guān)注點(diǎn);可以將切面看作是切點(diǎn)(Pointcut)和通知(Advice)的組合。切面定義了在何處(切點(diǎn))以及何時(shí)(通知)應(yīng)用橫切邏輯。

五種通知類型

在 Spring AOP 中,通知(Advice)是指在程序執(zhí)行過程中插入的代碼,它定義了在何時(shí)以及在什么情況下進(jìn)行切面的操作。通知是切面中的實(shí)際動(dòng)作部分,是橫切關(guān)注點(diǎn)的具體實(shí)現(xiàn);直觀來說就是要插入的那一組方法。

除了上面提到的在執(zhí)行方法之前執(zhí)行的 Before Advice,還有其他四種類型的通知,也就是說 Spring AOP 為我們提供了五個(gè)插入代碼的位置選擇。

前置通知(Before Advice)

在目標(biāo)方法執(zhí)行之前執(zhí)行的通知??梢杂脕韴?zhí)行日志記錄、安全檢查等。

@Aspect
@Component
public class LoggingAspect {@Before("execution(* com.example.service.*.*(..))")public void beforeAdvice() {System.out.println("前置通知:方法調(diào)用之前執(zhí)行");}
}

后置通知(After Advice)

在目標(biāo)方法執(zhí)行之后執(zhí)行的通知,無論方法是成功返回還是拋出異常。常用于清理資源等。

@Aspect
@Component
public class LoggingAspect {@After("execution(* com.example.service.*.*(..))")public void afterAdvice() {System.out.println("后置通知:方法調(diào)用之后執(zhí)行");}
}

返回后通知(After Returning Advice)

在目標(biāo)方法成功返回結(jié)果之后執(zhí)行的通知。可以用來記錄返回值或?qū)Ψ祷刂颠M(jìn)行處理。

@Aspect
@Component
public class LoggingAspect {@AfterReturning(pointcut = "execution(* com.example.service.*.*(..))", returning = "result")public void afterReturningAdvice(Object result) {System.out.println("返回后通知:方法返回值為 " + result);}
}

拋出異常后通知(After Throwing Advice)

在目標(biāo)方法拋出異常后執(zhí)行的通知。可以用來記錄異常信息或執(zhí)行異常處理邏輯。

@Aspect
@Component
public class LoggingAspect {@AfterThrowing(pointcut = "execution(* com.example.service.*.*(..))", throwing = "exception")public void afterThrowingAdvice(Exception exception) {System.out.println("拋出異常后通知:異常為 " + exception.getMessage());}
}

環(huán)繞通知(Around Advice)

環(huán)繞通知在目標(biāo)方法執(zhí)行的前后都執(zhí)行,可以完全控制目標(biāo)方法的執(zhí)行,包括決定是否執(zhí)行目標(biāo)方法,以及在目標(biāo)方法執(zhí)行前后添加自定義邏輯。環(huán)繞通知最為強(qiáng)大和靈活。

@Aspect
@Component
public class LoggingAspect {@Around("execution(* com.example.service.*.*(..))")public Object aroundAdvice(ProceedingJoinPoint joinPoint) throws Throwable {System.out.println("環(huán)繞通知:方法調(diào)用之前");Object result = joinPoint.proceed();  // 執(zhí)行目標(biāo)方法System.out.println("環(huán)繞通知:方法調(diào)用之后");return result;}
}

這五種通知方式的執(zhí)行順序是這樣的:

  • 前置通知(Before Advice)
  • **環(huán)繞通知(Around Advice)**的前半部分
  • 目標(biāo)方法執(zhí)行
  • **環(huán)繞通知(Around Advice)**的后半部分
  • 返回后通知(After Returning Advice)(如果目標(biāo)方法成功返回)
  • 拋出異常后通知(After Throwing Advice)(如果目標(biāo)方法拋出異常)
  • 后置通知(After Advice)

切點(diǎn)表達(dá)式

前面提到過,切面直觀來講就是插入方法的位置;在前面五種通知類型中,我們已經(jīng)看到了如何通過注解選擇方法的執(zhí)行位置,但是諸如
* com.example.service.*.*(..)) 這樣,定位方法位置的格式其實(shí)是沒有提及的,這一部分重點(diǎn)來講一下如何配置方法的位置。

切點(diǎn)則表示一組 joint point,這些 joint point 或是通過邏輯關(guān)系組合起來,或是通過通配、正則表達(dá)式等方式集中起來,它定義了相應(yīng)的 Advice 將要發(fā)生的地方。

切點(diǎn)表達(dá)式由以下幾部分組成:

execution(modifiers-pattern? ret-type-pattern declaring-type-pattern? name-pattern(param-pattern) throws-pattern?)

其中,各部分的含義如下,注意上面的問號(hào)(?)表示可選

  • execution:指定切點(diǎn)類型為方法執(zhí)行。
  • modifiers-pattern:可選,方法的訪問修飾符,如 public、protectedprivate。通常省略不寫,表示任意訪問修飾符。
  • ret-type-pattern:方法的返回類型模式,例如 void、String、``(任意返回類型)。
  • declaring-type-pattern:可選,方法所在類的全限定名稱模式,如 com.example.service.*。指定要匹配的類或包。
  • name-pattern:方法名稱模式,如 Service、get*。支持通配符 ``(匹配任意字符序列)和 ..(匹配任意數(shù)量和類型的參數(shù))。
  • param-pattern:方法參數(shù)模式,如 ()(無參數(shù))、(*)(一個(gè)任意類型的參數(shù))、(..)(任意數(shù)量和類型的參數(shù))。
  • throws-pattern:可選,方法可能拋出的異常模式。

下面來做幾個(gè)小練習(xí)

1)指定 com.example.service 包下的所有類的所有方法:

@Pointcut("execution(* com.example.service.*.*(..))")
private void serviceMethods() {}

2)com.example.service 包下所有類的方法中第一個(gè)參數(shù)為 String 類型的方法

@Pointcut("execution(* com.example.service.*.*(String, ..))")
private void stringParamMethods() {}

通過上面的練習(xí),相信大家對切點(diǎn)表達(dá)式的書寫方式有了一定的掌握,下面我們來看看,除了 execution 方法執(zhí)行切點(diǎn),Spring 還為我們提供了哪些指定切點(diǎn)的方式

within:限定匹配特定類型的連接點(diǎn)。within(com.example.service.*) 匹配 com.example.service 包及其子包中所有方法。

this:限定匹配特定類型的 bean。this(com.example.service.MyService) 匹配實(shí)現(xiàn) com.example.service.MyService 接口的 bean。

target:限定匹配特定類型的目標(biāo)對象。target(com.example.service.MyService) 匹配目標(biāo)對象是 com.example.service.MyService 的連接點(diǎn)。

args:限定匹配特定參數(shù)類型的方法。args(String, ..) 匹配第一個(gè)參數(shù)是 String 類型的方法。

@annotation:限定匹配特定注解的方法。@annotation(org.springframework.transaction.annotation.Transactional) 匹配標(biāo)注有 @Transactional 注解的方法。

因?yàn)?within、this 和 target,都可以通過 execution 作為一定程度上的替代,所以這里我們重點(diǎn)關(guān)注一下匹配特定注解的方式,即 @annotation 即可。

但同時(shí),這些表達(dá)式其實(shí)是可以共用的,比如通過這樣的方式:

@Before("execution(* com.example.service.UserService.getUserById(int)) && args(userId)")public void logBeforeGetUserById(JoinPoint joinPoint, int userId) {System.out.println("Before calling getUserById with userId: " + userId);}

上面的 userId 參數(shù)是通過切點(diǎn)表達(dá)式中的 args(userId) 指定的,所以在方法體內(nèi)可以直接使用 userId 參數(shù)來獲取方法執(zhí)行時(shí)的具體值;但如果僅僅使用 joinPoint 的話就需要 getArgs() 再拿取參數(shù)了;這里只涉及寫法上的偏好,我們平時(shí)使用的大部分的內(nèi)容通過 execution 和 @annotation 都是可以實(shí)現(xiàn)的。

正式使用

通過前面的介紹,我們已經(jīng)辨析了 AOP 的基本概念,了解了控制何時(shí)執(zhí)行邏輯的通知類型(Advice),定義在什么位置執(zhí)行的切點(diǎn)表達(dá)式(PointCut),下面我們正式來嘗試使用 AOP 來解決一些現(xiàn)實(shí)的問題。

就舉一個(gè)前面提到的日志記錄的 AOP 吧

定義一個(gè)簡單的服務(wù)類

@Service
public class UserService {public String getUserById(int userId) {// 模擬方法體return "User: " + userId;}
}

創(chuàng)建日志記錄的切面類

@Aspect
@Component
public class LoggingAspect {@Before("execution(* com.example.service.UserService.getUserById(int))")public void logBeforeGetUserById(JoinPoint joinPoint) {// 獲取方法參數(shù)Object[] args = joinPoint.getArgs();System.out.println("Before calling getUserById with userId: " + args[0]);}@AfterReturning(pointcut = "execution(* com.example.service.UserService.getUserById(int))", returning = "result")public void logAfterReturningGetUserById(JoinPoint joinPoint, Object result) {System.out.println("After returning from getUserById with result: " + result);}
}

然后我們?nèi)プ鲆粋€(gè)簡單的測試,可以看到如下的輸出:

Before calling getUserById with userId: 123
After returning from getUserById with result: User: 123
User retrieved: User: 123

關(guān)于 JoinPoint 和 ProceedingJoinPoint

在 Spring AOP 中,JoinPointProceedingJoinPoint 是兩個(gè)重要的接口,用于在切面中獲取方法執(zhí)行時(shí)的信息和控制方法執(zhí)行;我們在書寫切面邏輯的時(shí)候,需要的大部分參數(shù)或者方法信息等,都是從這里面獲取的。

JoinPoint 接口

JoinPoint 接口是 Spring AOP 提供的一個(gè)核心接口,用于描述正在執(zhí)行的連接點(diǎn)(join point),它可以用來獲取方法的簽名、參數(shù)等信息,但是不能直接控制方法的執(zhí)行流程。

常用方法

Signature getSignature(); // 獲取代表被通知方法簽名的對象,可以進(jìn)一步獲取方法名、聲明類型等信息。Object[] getArgs(); // 獲取被通知方法的參數(shù)對象數(shù)組。Object getTarget(); // 獲取目標(biāo)對象,即被通知的目標(biāo)類實(shí)例。Object getThis(); // 獲取代理對象的引用,即代理對象本身。Object[] getArgs(); // 獲取調(diào)用方法時(shí)傳遞的參數(shù)

其中有個(gè)特殊一點(diǎn)的是 Signature,方法簽名接口:

public interface Signature {String toString(); // 返回方法的字符串表示形式。String toShortString(); // 返回方法的簡短字符串表示形式。String toLongString(); // 返回方法的長字符串表示形式。String getName();// 獲取方法名。 int getModifiers(); // 獲取方法的修飾符,返回一個(gè)整數(shù),具體取值需要通過 java.lang.reflect.Modifier 類來解析。Class getDeclaringType(); // 獲取聲明該方法的類的 Class 對象。String getDeclaringTypeName(); // 獲取聲明該方法的類的全限定名。
}

大家可以自己寫個(gè)方法測試一下,這里就不過多贅述了。

ProceedingJoinPoint 接口

ProceedingJoinPoint 接口繼承自 JoinPoint 接口,它擴(kuò)展了 JoinPoint 接口,提供了控制方法執(zhí)行流程的能力。通常在 Around Advice 中使用 ProceedingJoinPoint 來調(diào)用目標(biāo)方法,并可以控制是否繼續(xù)執(zhí)行該方法,以及在執(zhí)行前后進(jìn)行額外的處理。

常用方法

Object proceed() throws Throwable; // 繼續(xù)執(zhí)行連接點(diǎn)(即目標(biāo)方法),返回方法的返回值。Object proceed(Object[] args) throws Throwable; // 按照給定的參數(shù)繼續(xù)執(zhí)行連接點(diǎn)。

由于是繼承,所以 JoinPoint 提供的方法,也都可以使用。

區(qū)別和用途

  • JoinPoint 主要用于獲取方法的元數(shù)據(jù)信息,如方法名、參數(shù)等,不具備控制方法執(zhí)行流程的能力。
  • ProceedingJoinPoint 繼承自 JoinPoint,可以控制方法的執(zhí)行流程,在 Around Advice 中使用,可以決定是否繼續(xù)執(zhí)行目標(biāo)方法,以及在執(zhí)行前后進(jìn)行額外的處理。
http://www.risenshineclean.com/news/59715.html

相關(guān)文章:

  • 商丘做網(wǎng)站哪家好上海廣告推廣
  • 網(wǎng)站開發(fā)功能模塊出錯(cuò)seo課培訓(xùn)
  • 哪個(gè)網(wǎng)站做醫(yī)學(xué)培訓(xùn)好seo工作內(nèi)容和薪資
  • 浙江嘉興seo網(wǎng)站優(yōu)化推廣網(wǎng)絡(luò)推廣宣傳
  • 網(wǎng)站建設(shè)價(jià)格自動(dòng)點(diǎn)擊器怎么用
  • 廣西備案工信部網(wǎng)站營銷型網(wǎng)站內(nèi)容
  • 潮州市住房和城鄉(xiāng)建設(shè)局網(wǎng)站站長工具大全
  • b2b網(wǎng)站制作任務(wù)推廣引流平臺(tái)
  • wordpress 布局修改西安seo托管
  • 尋找網(wǎng)站建設(shè)_網(wǎng)站外包如何優(yōu)化網(wǎng)頁
  • 青島網(wǎng)站建設(shè)找潤商大連seo按天付費(fèi)
  • 房地產(chǎn)行業(yè)網(wǎng)站跟我學(xué)seo從入門到精通
  • 重慶做網(wǎng)站價(jià)格百度一下首頁網(wǎng)址
  • 歐美網(wǎng)站建設(shè)排名北京網(wǎng)站seo服務(wù)
  • 如何在圖片上添加文字做網(wǎng)站網(wǎng)站備案查詢官網(wǎng)
  • 資源網(wǎng)站如何做網(wǎng)上開店如何推廣自己的網(wǎng)店
  • 公司域名注冊網(wǎng)站哪個(gè)好合肥網(wǎng)絡(luò)推廣培訓(xùn)學(xué)校
  • 養(yǎng)生館室內(nèi)設(shè)計(jì)手機(jī)網(wǎng)站seo免費(fèi)軟件
  • 網(wǎng)站設(shè)計(jì)畢業(yè)論文任務(wù)書撫順優(yōu)化seo
  • 群暉ds1817做網(wǎng)站國外網(wǎng)站制作
  • 銅川公司做網(wǎng)站企業(yè)查詢系統(tǒng)官網(wǎng)
  • 南通網(wǎng)站優(yōu)化營銷渠道模式有哪些
  • 做淘寶聯(lián)盟網(wǎng)站要多少錢建設(shè)網(wǎng)頁
  • 公司營銷網(wǎng)站制作下載百度官方網(wǎng)站
  • 淫穢色情網(wǎng)站境外的南寧網(wǎng)站建設(shè)
  • 母嬰網(wǎng)站建設(shè)初衷如何免費(fèi)注冊網(wǎng)站平臺(tái)
  • 2023貴陽疫情最新消息今天seo營銷名詞解釋
  • 天河區(qū)做網(wǎng)站上海搜索關(guān)鍵詞排名
  • 怎樣搭建網(wǎng)站百度廣告推廣怎么做
  • 手機(jī)怎么做網(wǎng)站添加背景音樂重慶黃埔seo整站優(yōu)化