SpringAop--Java面試題

curry库-04049發表於2024-11-25

目錄
  • Spring 的事務隔離級別?
  • Spring 的事務傳播行為?
    • 1>概念
    • 2>事務傳播的配置
  • 什麼是AoP?AoP與ooP有何區別?
    • 1>Aop的概念
    • 2>Aop和OOp的區別
  • 什麼是連線點、切點和增強(或通知)?
    • 連線點
    • 切點
    • 增強
  • 什麼是織入?有哪些織入方式?
    • 1>織入概念
    • 2>織入方式
  • 什麼是切面?SpringAoP如何定義一個切面?
    • 1>切面
    • 2>SpringAop定義切面
      • 1. 建立切面類
      • 2. 定義切點(Pointcut)
      • 3. 定義增強(Advice)
      • 4. 配置Spring以啟用AOP
      • 5. 將切面加入Spring容器
  • SpringAoP底層實現機制如何?
    • JDK動態代理
    • CGLIB動態代理
    • 織入機制
  • 有哪些型別的增強(或通知)?

Spring 的事務隔離級別?

事務隔離的概念:多個事務可以同時訪問資料庫中的資料,當多個事務在資料庫中同時訪問(併發)時,資料庫的一致性可能會受到破壞,從而導致資料出現問題

為了解決資料庫的訪問併發問題,Spring有四種事務隔離級別

  • 未授權讀取、讀未提交

    一個事務已經開始寫資料,另一個事務不允許同時寫操作,但允許其他事務讀此行資料

  • 授權讀取、讀提交(spring預設的事務隔離級別)

    讀取資料的事務允許其他事務繼續訪問該行資料,但是未提交的寫事務將會禁止其他事務訪問該行

  • 可重複讀取

    讀取資料的事務將會禁止寫事務(但允許讀事務),寫事務則禁止任何其他事務

  • 序列化

    嚴格的事務隔離級別,要求事務序列化執行,事務只能一個個執行(可以理解為序列執行),不能併發執行

Spring 的事務傳播行為?

1>概念

系統中的一些方法交由spring來管理事務,當這些方法出現巢狀呼叫的時候,事務的表現行為就由事務的傳播來決定

2>事務傳播的配置

透過@Transactional註解中的propagation屬性來指定事務的傳播行為

事務傳播行為型別 說明
REQUIRED 如果當前事務管理器中沒有事務,就新建一個事務,如果已經存在一個事務中,加入到這個事務中。這是最常見的選擇,是預設的傳播行為
SUPPORTS 支援當前事務,如果當前事務管理器中沒有事務,就以非事務方式執行。
MANDATORY 使用當前的事務,如果當前事務管理器中沒有事務,就丟擲異常。
REQUIRES_NEW 新建事務,如果當前事務管理器中存在事務,把當前事務掛起,然後會新建一個事務。
NOT_SUPPORTED 以非事務方式執行操作,如果當前事務管理器中存在事務,就把當前事務掛起。
NEVER 以非事務方式執行,如果當前事務管理器中存在事務,則丟擲異常。
NESTED 如果當前事務管理器中存在事務,則在巢狀事務內執行;如果當前事務管理器中沒有事務,則執行與PROPAGATION_REQUIRED類似的操作。

注意:這 7 種傳播行為有個前提,他們的事務管理器是同一個的時候,才會有上面描述中的表現行為。Spring 事務傳播預設使用 REQUIRED 型別

什麼是AoP?AoP與ooP有何區別?

1>Aop的概念

面向切面程式設計,透過預編譯方式和執行期動態代理實現程式功能統一維護的一種技術

  • 在Spring中Aop是oop的延續和有益補充,函數語言程式設計的一種泛型
  • 在Spring中提供了AOP的豐富支援,允許透過分離應用的業務邏輯與系統級服務和事務管理進行內聚性的併發

2>Aop和OOp的區別

OOP是物件導向程式設計(兩種程式設計思想,在目標上有本質的差異)

  • OOP(物件導向程式設計):針對業務處理過程的實體及其屬性和行為進行抽象封裝為物件,以物件作為最基本的邏輯處理單元,並關注物件與物件之間的關係
  • AOP(面向切面程式設計):針對業務處理過程中的切面進行提取,它所面對的是處理過程中的某個步驟或階段,以切面作為最基本的邏輯處理單元,以獲得邏輯過程中各部分之間低耦合性的隔離效果

什麼是連線點、切點和增強(或通知)?

連線點

往程式中插入程式碼的點(比如類初始化前後,某個方法呼叫前後)

切點

定位到特定的連線點,切點相當於查詢條件,一個切點可以匹配多個連線點(插入程式碼位置的查詢條件)

增強

織入到目標類連線點上的一段程式程式碼,在SpringAop中,增強除了用於描述一段程式程式碼外,還擁有另一個和連線點相關的資訊

什麼是織入?有哪些織入方式?

1>織入概念

是將增強新增到目標類具體連線點上的過程

2>織入方式

  • 編譯器織入:要求使用特殊的編譯器

  • 類裝載器織入:要求使用特殊的類裝載器

  • 動態代理織入:在執行期間為目標類新增增強生成子類的方式

    (SpringAop採用動態代理織入方式)

什麼是切面?SpringAoP如何定義一個切面?

1>切面

切點+增強組成(包括橫切邏輯和連線點的定義)

Spring AOP 負責實施切面的框架,它將切面所定義的橫切邏輯織入到切面所指定的連線點中

2>SpringAop定義切面

在Spring AOP中定義一個切面(Aspect)通常涉及以下幾個步驟:

1. 建立切面類

首先,你需要建立一個類來表示切面。這個類將包含切點(Pointcut)和增強(Advice)。

import org.aspectj.lang.annotation.Aspect;
import org.aspectj.lang.annotation.Pointcut;
import org.aspectj.lang.annotation.Before;
import org.springframework.stereotype.Component;

@Aspect // 標識這是一個切面類
@Component // 使Spring能夠掃描並管理這個切面
public class MyAspect {
    // 這裡將定義切點和增強
}
2. 定義切點(Pointcut)

切點定義了增強邏輯應該應用到哪些連線點上。你可以使用@Pointcut註解來宣告一個切點。

@Pointcut("execution(* com.yourpackage..*(..))") // 定義切點表示式
public void myPointcut() {
    // 切點方法體為空
}

這裡的表示式"execution(* com.yourpackage..*(..))"是一個AspectJ表示式,它匹配com.yourpackage包及其子包中所有類的所有方法。

3. 定義增強(Advice)

增強是切面中的核心,它定義了在切點處應該執行的邏輯。Spring AOP支援多種型別的增強,包括:

  • @Before:在切點方法執行之前執行
  • @After:在切點方法執行之後執行
  • @AfterReturning:在切點方法成功執行之後執行
  • @AfterThrowing:在切點方法丟擲異常之後執行
  • @Around:在切點方法執行之前和之後都執行

例如,使用@Before註解定義一個前置增強:

@Before("myPointcut()") // 引用上面定義的切點
public void beforeAdvice(JoinPoint joinPoint) {
    // 增強邏輯
    System.out.println("Before method: " + joinPoint.getSignature().getName());
}
4. 配置Spring以啟用AOP

如果你使用的是Spring Boot,通常不需要額外配置,因為Spring Boot自動配置了AOP。如果你使用的是Spring的XML配置,你需要在配置檔案中啟用AOP:

<aop:aspectj-autoproxy/>
5. 將切面加入Spring容器

在Spring中,你可以透過@Component註解將切面類加入到Spring容器中,如上面的示例所示。這樣,Spring就能夠自動識別和管理這個切面。

總結

定義一個切面涉及到建立切面類、定義切點、定義增強邏輯,並將切面加入到Spring容器中。Spring AOP透過代理機制在執行時織入增強,使得你可以在不修改業務邏輯程式碼的情況下,為應用程式新增橫切關注點。

SpringAoP底層實現機制如何?

Spring AOP的底層實現機制主要基於動態代理技術,它透過代理模式在執行時動態地為物件新增額外的功能,這些功能通常被稱為“橫切關注點”,如日誌記錄、事務管理等。Spring AOP支援兩種動態代理機制:JDK動態代理和CGLIB動態代理。

JDK動態代理

Spring預設使用JDK的動態代理實現AOP。當目標物件實現了一個或多個介面時,Spring會使用JDK的Proxy類和InvocationHandler介面來建立目標物件的代理。在這種機制下,代理物件會實現與目標物件相同的介面,並在代理物件的方法呼叫中,透過反射機制呼叫InvocationHandlerinvoke方法,從而在方法執行前後新增額外的行為。

CGLIB動態代理

對於沒有實現介面的目標物件,Spring AOP會使用CGLIB庫來建立代理。CGLIB透過建立目標類的子類來實現代理,這個子類會覆蓋目標類的方法,並在這些方法中新增額外的邏輯。CGLIB使用MethodInterceptor來定義代理的行為,捕獲方法呼叫,並在方法呼叫前後插入自定義的邏輯。

織入機制

Spring AOP的織入機制負責將切面應用到目標物件上,建立新的代理物件。織入可以在不同的階段發生:

  • 編譯時織入(Compile-Time Weaving, CTW):在原始碼編譯成位元組碼時進行織入,需要AspectJ編譯器支援。
  • 類載入時織入(Load-Time Weaving, LTW):在類載入到JVM時進行織入,透過自定義類載入器實現。
  • 執行時織入(Runtime Weaving):在應用程式執行時進行織入,Spring AOP預設使用這種方式,透過代理機制實現。

Spring AOP透過這些機制,能夠在不修改業務邏輯程式碼的情況下,為應用程式提供靈活的橫切關注點管理,增強了程式碼的模組化和重用性。

有哪些型別的增強(或通知)?

  • 前置增強 目標方法執行前實施增強
  • 後置增強 在目標方法後實施增強
  • 環繞增強 在目標方法執行前後實施增強
  • 丟擲異常增強 在目標方法丟擲異常後實施增強
  • 引介增強 在目標類中新增一些新的方法和屬性

相關文章