A-O-P 一篇概覽

2023-04-27 15:00:32

一、什麼是AOP?

AOP 即 Aspect-oriented Programming,Aspect 切面,什麼是切面,就是一條大路上的收費站,檢查站,首先它是一個統一的功能單元,或是收費、或是檢查,其次它可以決定對誰收費,對誰收多少費,對誰檢查。與之相對的是 OOP 即 Object-oriented Programming,Object 物件,物件就是大路上的一輛輛汽車,每輛汽車都有一套完成的功能系統,有發動機、車架、車輪、方向盤等,每輛車又各自不同,或是小轎、或是SUV、又或是貨車等等,AOP 是對 OOP 的補充,是程式結構涉及的一種方式。

二、核心概念

  • Aspect:模組化的關注點(切面),例如事務。通常以 @Aspect 註解類形式應用。一個小容器

    package com.xyz;
    
    import org.aspectj.lang.annotation.Aspect;
    
    @Aspect
    public class NotVeryUsefulAspect {
    }
  • Join point::程式執行過程中的一個點,例如一個方法,或者一個例外處理。Spring AOP 中,通常代表一個方法的執行。在何處執行

    @Before("execution(* com.xyz.dao.*.*(..))")
    public void doAccessCheck(JoinPoint jp) {
        // ...
    }
    

    可以通過 JointPoint 獲取執行點的一系列資料:

    • getArgs():方法引數。

    • getThis():返回代理物件。

    • getTarget():返回被代理的物件。

    • getSignature():方法描述。

  • Advice:在 joint point 處需要執行的操作。包括 "around"、"before" 及 "after" 等。advice 通常會被模組化為攔截器,多個 advices 以攔截器鏈的形式作用於 joint point。執行什麼

    @After("execution(* com.xyz.dao.*.*(..))")
    
    public void doAccessCheck() {
        // ...
    }

    關於 advice 順序:
    spring aop 中定義順序:@Around、@Before、@After、@AfterReturning、@AfterThrowing
    應用 AspectJ 則遵從 @After 作為最終執行順序,於 @AfterReturning、@AfterThrowing 之後執行。
    同一個 joint point 處的同類 advice 以 @Order 執行執行順序。

  • Pointcut:用以匹配 joint point 的斷言,可以稱之為代表一系列 joint point。結合 Advice 使用。匹配何處執行語意

    @Pointcut("execution(public * *(..))")
    public void publicMethod() {}
    Pointcut 使得 advice 可以作用於目標物件,同時又獨立於物件,是實現面向切面的關鍵概念。
  • Target object:advices 執行的目標物件。代理物件

  • AOP proxy:代理,用以實現切面合約。JDK動態代理或者CGLIB 代理。

  • Weaving:織入,將切面和其它應用物件連結在一起來建立執行物件。組裝。

三、能力和目標

Spring AOP 目前只支援方法級別的 joint point(spring bean 中的方法),如果需要其它粒度,如屬性欄位,可以使用 AspectJ。

Spring AOP 沒有實現完整的 AOP 功能,它的出現旨在整合 AOP 功能和 Spring IoC 容器,用以解決企業實際應用中常見的問題。

Spring AOP 和 AspectJ 並非競爭關係,它們各自都是非常成熟的框架,適用於不同的目的。Spring 可以在基於 Spring 框架的應用架構中無縫整合 Spring AOP、IoC 及 AspectJ,以完整地使用 AOP 功能。

四、代理

Spring AOP 是基於代理的,預設使用 JDK 動態代理,用以實現介面代理。

非介面代理需要使用 CGLIB。 

五、AspectJ

1、AnnotationAwareAspectJAutoProxyCreator

ApplicationContext:入口。

AspectJAutoProxyBeanDefinitionParser:AspectJ 解析器,自動發現註冊 AspectJ 風格的切面。

AnnotationAwareAspectJAutoProxyCreator 會根據定義的切點來自動代理相匹配的 bean。AnnotationAwareAspectJAutoProxyCreator 的層次結構如下:

AnnotationAwareAspectJAutoProxyCreator 實現了 BeanPostProcessor 介面,會在對應 Bean 範例化後應用此 BeanPostProcessor。

AnnotationAwareAspectJAutoProxyCreator 用於處理所有 AspectJ 宣告的切面。

2、AspectJProxyFactory

基於 AspectJ 的代理工廠。可以用於程式設計方式建立包含切面的物件代理。

//建立代理工廠
AspectJProxyFactory factory = new AspectJProxyFactory(targetObject);

// 新增 AspectJ aspect,可以多次新增,可以使 class 或者 instance。
factory.addAspect(SecurityManager.class); //.addAspect(usageTracker);

// 獲取物件代理
MyInterfaceType proxy = factory.getProxy();