1. 程式人生 > >二、Spring AOP原理

二、Spring AOP原理

學習內容

1、AOP簡述

2、Spring AOP簡介

3、Spring AOP設計

4、Spring AOP實現


 

一、AOP簡述:

AOP:Aspct-Oriented Programming,意思為面向切面。AOP把軟體系統分為兩個部分:核心關注點和橫切關注點。核銷關注點即為業務程式碼,而橫切關注點為業務無關程式碼,例如許可權認證、日誌、事務處理等。AOP技術有AspectJ、JBoss-AOP、Spring AOP等。

1、Aspect(切面):將影響了多個類的公共行為封裝到一個可重用模組,該模組即為切面。

2、Joinpoint(連線點): 一個應用執行過程中能夠插入一個切面的點。

SpringAOP的連線點只能是方法。

3、Pointcut(切點): 連線點的集合。

4、Advice(通知/增強):在特定的連線點,AOP框架執行的動作。描述切面要完成的工作,還解決何時執行這個工作。Spring 切面可應用的 5 種通知型別:

a、Before——在方法呼叫之前呼叫通知

b、After——在方法完成之後呼叫通知,無論方法執行成功與否

c、After-returning——在方法執行成功之後呼叫通知

d、After-throwing——在方法丟擲異常後進行通知

e、Around——通知包裹了被通知的方法,在被通知的方法呼叫之前和呼叫之後執行

5、Introduction(引入):引入是一種特殊的增強,它為目標類新增一些屬性和方法。

如果一個業務類沒有實現某個介面,通過AOP的引介功能,可以動態地為該業務類新增介面的實現邏輯,讓業務類成為這個介面的實現類。

Spring允許引入新的介面到任何被通知的物件。例如,可以使用一個引入使任何物件實現 IsModified介面,來簡化快取。Spring中要使用Introduction, 可有通過DelegatingIntroductionInterceptor來實現通知,通過DefaultIntroductionAdvisor來配置Advice和代理類要實現的介面。

6、Target Object(目標物件): 包含連線點的物件。也被稱作被通知或被代理物件。

7、Weave(織入): 織入是將切面應用到目標物件來建立的代理物件過程。根據不同的實現技術,AOP有三種織入的方式:

a、編譯期織入,這要求使用特殊的Java編譯器。

b、類裝載期織入,這要求使用特殊的類裝載器。

c、動態代理織入,在執行期為目標類新增增強生成子類的方式。

SpringAOP採用動態代理織入,而AspectJ採用編譯期織入和類裝載期織入。


二、Spring AOP簡介

1、Spring AOP對相關術語的實現

a、Advice

繼承關係,以實現類MethodBeforeAdvice為例

 

實現MethodBeforeAdvice的before回撥方法就行

public interface MethodBeforeAdvice extends BeforeAdvice {

void before(Method var1, Object[] var2, Object var3) throws Throwable;

}

Spring org.springframework.aop 下的其他Advice實現類,例如AfterReturningAdvice等,設計都是一致的。

b、Pointcut

繼承關係,以實現類JdkRegexpMethodPointcut為例

 


public interface Pointcut {

    Pointcut TRUE = TruePointcut.INSTANCE;

    ClassFilter getClassFilter();
    
    MethodMatcher getMethodMatcher();

}
public interface MethodMatcher {

    MethodMatcher TRUE = TrueMethodMatcher.INSTANCE;

    boolean matches(Method var1, Class<?> var2);

    boolean isRuntime();

    //當返回true時,表名當前方法需要增強。以JDK動態代理織入方式為例,該方法的
    //呼叫在,攔截介面的invoke()方法中呼叫
    boolean matches(Method var1, Class<?> var2, Object[] var3);

}

除了JdkRegexpMethodPointcut,還有NameMatchMethodPointcut,以方法名作為匹配

c、Advisor

用於結合,Advice和Pointcut,以DefaultPointcutAdvisor為例,繼承關係為

 


三、Spring AOP設計

1、設計

Spring AOP的技術實現是以動態代理為基礎,也就是說Spring AOP功能就是使用動態代理實現的。


四、Spring AOP實現

1、如何生成代理物件?ProxyCreatorSupport

繼承關係

 

實現子類有三個

 

AspectJProxyFactory:支援整合AspectJ和Spring。

ProxyFactoryBean:支援在Ioc容器中完成宣告配置Spring AOP.

ProxyFactory:支援程式設計式的使用Sprng AOP功能。

 

2、ProxyFactoryBean、ProxtyFactory實現AOP功能

使用ProxyFactoryBean,是Ioc環境中建立Aop應用的最底層方式,最為靈活。Spring通過ProxyFactoryBean完成對AOP功能的封裝。

如何使用?

//定義一個介面

public interface UserDao {

    void addUser();

}

//目標物件實現介面並重寫方法

public class UserDaoImpl implements UserDao {

    @Override
    public void addUser() {

        System.out.println("新增使用者");

    }

}

//實現增強類的介面

public class LogBefore implements MethodBeforeAdvice {

    //arg0 目標類的方法
    arg1 目標類的入引數
    arg2 目標類
    @Override
    public void before(Method arg0, Object[] arg1, Object arg2) throws Throwable {

        System.out.println("新增日誌");

    }

}

ProxtyFactory以程式設計形式

public class Test {

    public static void main(String[] args) throws Exception{

        LogBefore log = new LogBefore();

        UserDao userDao = new UserDaoImpl();

        ProxyFactory proxyf = new ProxyFactory();

        //設定目標物件
        proxyf.setTarget(userDao);

        //設定增強類物件
        proxyf.addAdvice(log);

        //獲得代理物件
        UserDao up = proxyf.getProxy();

        up.addUser();

    }

}

ProxyFactoryBean通過xml配置代理。

<bean id="logBefore" class="com.cong.LogBefore"/>

<bean id="target" class="com.cong.UserDaoImpl"/>

<bean id="userDao" class="org.springframework.aop.framework.ProxyFactoryBean"
p:proxyInterfaces="com.cong.UserDao"
p:interceptorNames="logBefore"
p:target-ref="target"/>

 

target:代理的目標物件

proxyInterfaces:代理所需要實現的介面,可以多個介面。該屬性還有一個別名是Interfaces

interceptorNames:需要植入目標物件的bean列表。採用bean的名稱指定。

這些bean必須實現類 org.aopalliance.intercept.MethodInterceptor

或 org.springframework.aop.Advisor的bean ,配置中的順序對應呼叫的順序。

proxyTargetClass:是否對類進行代理,而不是進行對介面進行代理。

設定為true時,使用CGLib代理,且proxyInterfaces屬性被ProxyFactoryBean忽略。

 

3、代理物件的生成

ProxyFactoryBean為FactoryBean,所以,以getObject()為入口可知,代理物件的生成,由AopProxy生成,其實現類有兩個,Cglib2AopProxy、JdkDynamicProxy,所以Spring分別通過CGLIB和JDK來生成代理物件。

而AopProxy的生成由DefaultAopProxyFactory來生成,具體生成哪個實現類由代理的模板類是否實現介面來判斷,如果是則生成JdkDynamicAopProxy,否則使用Cglib2AopProxy,或者配置強制使用Cglib2AopProxy。這兩個類都有直接實現各自代理的攔截器介面,如JdkDynamicAopProxy實現了InvocationHandler介面的invoke()方法,Cglib2AopProxy實現了DynamicAdvicedInterceptor介面的intercept()方法,所以Spring AOP具體的增強就是通過攔截器來完成的。