天天看點

Spring AOP(二)AOPAlliance與SpringAOP核心接口介紹AOP聯盟Spring AOP

目錄

  • AOP聯盟
    • 1. Advice、MethodInterceptor攔截器(invoke方法:調用invocation.proceed)
    • 2.Joinpoint 、MethodInvocation連接配接點(proceed方法:執行此攔截點)
  • Spring AOP
    • 1.Advice 通知-擴充接口(MethodBeforeAdvice、ThrowsAdvice、AfterReturningAdvice)
    • 2.MethodInterceptor方法攔截器-擴充接口(對Advice的包裝)
    • 3.MethodInvocation 方法調用連接配接點-擴充接口ProxyMethodInvocation、實作類ReflectiveMethodInvocation
    • 4. Spring新增接口:Pointcut 切點
    • 5. Spring新增接口:Advisor 通知器
    • 總結
AOP聯盟是java對于AOP提供的一系列标準接口,頂層接口有:
	Advice通知,及其繼承接口MethodInterceptor方法攔截器;
	JointPoint連接配接點,及其繼承接口MethodInvocation。

Spring或其他具有AOP概念的架構都會依賴于此,從Spring擴充的接口來看,對于AOP的支援局限于方法的攔截。

比如Spring AOP中就實作了Advice的擴充接口:方法前置增強、方法後置增強、異常增強等;
另外還有對這些Advice的包裝實作:MethodInterceptor方法攔截器。

Spring中對于JoinPoint的實作包括了ProxyMethodInvocation,是AOP的核心類。

另外Spring新增了一個PointCut切點的概念,一個PointCut對應多個JointPoint。
           

在分析源碼實作之前,先來看一些基本概念與核心接口。

AOP聯盟

AOP Alliance 是java中對于面向切面提供了一系列标準化接口,Spring或其他具有AOP概念的架構會依賴這個包。

Spring AOP(二)AOPAlliance與SpringAOP核心接口介紹AOP聯盟Spring AOP

這個包中有兩個頂層接口:

  • Advice:代表要織入的邏輯
  • Joinpoint:連接配接點,增強邏輯的織入地點

1. Advice、MethodInterceptor攔截器(invoke方法:調用invocation.proceed)

Advice接口及其繼承接口:

  • Advice:增強(通知),代表要織入的邏輯
  • Interceptor:攔截器,代表了以攔截器方式去實作通知
  • MethodInterceptor:方法攔截器(Spring中提供了實作類)
  • ConstructorInterceptor:構造器攔截器

接口關系:

Advice
   |
   ├── Interceptor
   |       |
   |       ├── MethodInterceptor
   |       ├── ConstructorInterceptor

           

接口方法:

(注意此處的MethodInterceptor是org.aopalliance.intercept.MethodInterceptor而非cglib包中的同名接口)

public interface Advice {

}

public interface Interceptor extends Advice {

}
//Spring中實作了此接口:MethodBeforeAdviceInterceptor、AfterReturningAdviceInterceptor等
public interface MethodInterceptor extends Interceptor {
	//需要執行的時候,調用invocation.proceed()
    Object invoke(MethodInvocation invocation) throws Throwable;

}
public interface ConstructorInterceptor extends Interceptor  {

    Object construct(ConstructorInvocation invocation) throws Throwable;

}
           

2.Joinpoint 、MethodInvocation連接配接點(proceed方法:執行此攔截點)

Joinpoint接口及其繼承接口:

  • Joinpoint:連接配接點
  • Invocation:調用連接配接點, 表示程式中的調用 ,是一個可以被攔截器攔截的連接配接點
  • MethodInvocation:方法調用連接配接點(Spring中提供了實作類)
  • ConstructorInvocation:構造器調用連接配接點
Joinpoint
   |
   ├── Invocation
   |       |
   |       ├── MethodInvocation
   |       ├── ConstructorInvocation
           

接口方法:

(注意此處的Joinpoint是org.aopalliance.intercept.Joinpoint,而非指Spring中的org.aspectj.lang.JoinPoint)

public interface Joinpoint {

	// 執行此攔截點,并進入到下一個連接配接點
    Object proceed() throws Throwable;
	// 傳回儲存目前連接配接點靜态部分的對象
    Object getThis();
	// 傳回此靜态連接配接點  一般就為目前的Method
    AccessibleObject getStaticPart();

}
public interface Invocation extends Joinpoint {
	// 獲得參數,如方法入參
    Object[] getArguments();

}
//作為AOP Alliance中的底層接口,Spring AOP中實作了此接口:ReflectiveMethodInvocation
public interface MethodInvocation extends Invocation {
	// 傳回目前被調用的Method
    Method getMethod();

}
public interface ConstructorInvocation extends Invocation {

    Constructor<?> getConstructor();

}
           

Spring AOP

Spring AOP并不是自立門戶,而是在AOP聯盟定義的一系列接口上,提供實作類或者進行封裝。

1.Advice 通知-擴充接口(MethodBeforeAdvice、ThrowsAdvice、AfterReturningAdvice)

Spring對于Advice接口繼承擴充:

  • BeforeAdvice:前置增強
  • AfterAdvice:後置增強
  • MethodBeforeAdvice:方法前置增強
  • AfterReturningAdvice:方法後置增強
  • ThrowsAdvice:異常增強
Advice 
   |
   ├── Interceptor
   |       |
   |       ├── MethodInterceptor
   |       ├── ConstructorInterceptor
   |
   ├── BeforeAdvice
   |       |
   |       ├── MethodBeforeAdvice
   |
   ├── AfterAdvice
   |       |
   |       ├── ThrowsAdvice
   |       ├── AfterReturningAdvice 
           

各個接口中方法:

public interface BeforeAdvice extends Advice {

}
public interface MethodBeforeAdvice extends BeforeAdvice {

    void before(Method method, Object[] args, Object target) throws Throwable;

}
public interface AfterAdvice extends Advice {

}
public interface ThrowsAdvice extends AfterAdvice {

}
public interface AfterReturningAdvice extends AfterAdvice {

    void afterReturning(Object returnValue, Method method, Object[] args, Object target) throws Throwable;

}
           

2.MethodInterceptor方法攔截器-擴充接口(對Advice的包裝)

Spring中對于Advice接口繼承擴充:

  • IntroductionInterceptor:引介增強,類級别的增強器
  • MethodBeforeAdviceInterceptor
  • AfterReturningAdviceInterceptor
  • ThrowsAdviceInterceptor
  • … …
Advice 
   |
   ├── Interceptor
   |       |
   |       ├── MethodInterceptor
   |       |        |
   |       |        ├── IntroductionInterceptor
   |       |        ├── MethodBeforeAdviceInterceptor
   |       |        ├── AfterReturningAdviceInterceptor
   |       |        ├── ThrowsAdviceInterceptor
   |       ├── ConstructorInterceptor
   |
   ├── BeforeAdvice
   |       |
   |       ├── MethodBeforeAdvice
   |
   ├── AfterAdvice
   |       |
   |       ├── ThrowsAdvice
   |       ├── AfterReturningAdvice 
           

接口方法,以MethodBeforeAdviceInterceptor為例:

public class MethodBeforeAdviceInterceptor implements MethodInterceptor, Serializable {

	private MethodBeforeAdvice advice;
	// MethodBeforeAdviceInterceptor隻是将MethodBeforeAdvice進行了一個包裝
	public MethodBeforeAdviceInterceptor(MethodBeforeAdvice advice) {
		Assert.notNull(advice, "Advice must not be null");
		this.advice = advice;
	}

	@Override
	public Object invoke(MethodInvocation mi) throws Throwable {
		this.advice.before(mi.getMethod(), mi.getArguments(), mi.getThis() );
		return mi.proceed();
	}

}
           

同樣的,AfterReturningAdviceInterceptor是對AfterReturningAdvice的包裝、ThrowsAdviceInterceptor是對ThrowsAdvice的包裝。

3.MethodInvocation 方法調用連接配接點-擴充接口ProxyMethodInvocation、實作類ReflectiveMethodInvocation

Spring對于Joinpoint接口的繼承擴充:

  • ProxyMethodInvocation:繼承自MethodInvocation接口,是Spring AOP的核心接口
  • ReflectiveMethodInvocation:ProxyMethodInvocation的實作
Joinpoint
   |
   ├── Invocation
   |       |
   |       ├── MethodInvocation
   |        |        |
   |        |        ├── ProxyMethodInvocation
   |        |        |        |
   |        |        |        ├── ReflectiveMethodInvocation
   |       ├── ConstructorInvocation
           

接口方法:

public interface ProxyMethodInvocation extends MethodInvocation {

	Object getProxy();

	MethodInvocation invocableClone();

	MethodInvocation invocableClone(Object... arguments);

	void setArguments(Object... arguments);

	void setUserAttribute(String key, Object value);

	Object getUserAttribute(String key);
}
           

4. Spring新增接口:Pointcut 切點

Pointcut是Spring AOP新增的接口,定義了Joinpoint連接配接點的比對規則,即:一個Pointcut對應多個Joinpoint,也就是 Advice邏輯織入的Joinpoint連接配接點的集合

接口定義如下

public interface Pointcut {

    ClassFilter getClassFilter();

    MethodMatcher getMethodMatcher();

    Pointcut TRUE = TruePointcut.INSTANCE;

}
           

5. Spring新增接口:Advisor 通知器

Spring AOP新增了一個接口Advisor,用來包裝 Advice通知 和 Pointcut切點 兩個對象。

  • Advisor:持有一個Advice
  • PointcutAdvisor:在Advisor的基礎上,持有一個Pointcut
  • IntroductionAdvisor:引介切面
Advisor 
   |
   ├── PointcutAdvisor
   ├── IntroductionAdvisor

           

接口方法:

public interface Advisor {

    Advice getAdvice();

    boolean isPerInstance();
}

public interface PointcutAdvisor extends Advisor {

    Pointcut getPointcut();
}

public interface IntroductionAdvisor extends Advisor, IntroductionInfo {

	ClassFilter getClassFilter();

	void validateInterfaces() throws IllegalArgumentException;

}
           

總結

上述幾個概念之間的關系可以概括為

Spring AOP(二)AOPAlliance與SpringAOP核心接口介紹AOP聯盟Spring AOP

從Spring中所擴充的接口或者實作類來看,Spring 對 AOP 的支援局限于 方法的攔截。

(如果需求超過了簡單的方法調用,如構造器或屬性攔截,那麼需要考慮使用 AspectJ 來實作切面)