SpringAop篇 (1) AOP 基礎之動態代理的實現
阿新 • • 發佈:2019-01-10
介紹
Spring AOP 主要通過動態代理來實現的,所以我們需要在介紹 AOP 用法之前,先來介紹下動態代理的用法以及本質。
對於動態代理的理解可以借鑑普通代理模式。我們普通的Java代理需要為一個物件建立專門的代理物件,通過呼叫代理物件,來實現原物件的各種功能。
而動態代理區別於普通代理方式,動態代理是在執行時產生的代理類。
動態代理實現方式
-
通過實現 InvocationHandler 介面建立自己的呼叫處理器;
-
通過為 Proxy 類指定 ClassLoader 物件和一組 interface 來建立動態代理類;
-
通過反射機制獲得動態代理類的建構函式,其唯一引數型別是呼叫處理器介面型別;
-
通過建構函式建立動態代理類例項,構造時呼叫處理器物件作為引數被傳入。
-
介面:
public interface Action {
public int action();
}
- 實現類:
public class LogAction implements Action{
public int action(){
System.out.println("action");
return 20;
}
}
- 代理類 :
public class ActionInvocationHandlerImpl implements InvocationHandler { private Object action; public ActionInvocationHandlerImpl(Object action) { this.action = action; } public Action getAction(){ return (Action) Proxy.newProxyInstance(action.getClass().getClassLoader(), action.getClass().getInterfaces(), this); } /** * <pre> * 動態代理具體的實現類 * </pre> * * @param proxy 具體的代理物件 * @param method 當前呼叫的方法 * @param args 呼叫引數 */ @Override public Object invoke(Object proxy, Method method, Object[] args) throws Throwable { System.out.println("Before action"); Object value = method.invoke(action, args); System.out.println("End action"); return value; } }
- 例子:
public class Main {
public static void main(String[] args) {
Action action = new ActionInvocationHandlerImpl(new LogAction()).getAction();
action.action();
}
}
說明:
每一個動態代理類都必須要實現 InvocationHandler 這個介面(程式碼中的中介),並且每個代理類的例項都關聯到了一個handler,當我們通過代理物件呼叫一個方法的時候,這個方法的呼叫就會被轉發為由InvocationHandler這個介面的 invoke(對方法的增強就寫在這裡面) 方法來進行呼叫。
Proxy這個類的作用就是用來動態建立一個代理物件的類,它提供了許多的方法,但是我們用的最多的就是 newProxyInstance 這個方法:
public static Object newProxyInstance(ClassLoader loader, Class<?>[] interfaces, InvocationHandler h) throws IllegalArgumentException
//loader:一個ClassLoader物件,定義了由哪個ClassLoader物件來對生成的代理物件進行載入
//interfaces:一個Interface物件的陣列,表示的是我將要給我需要代理的物件提供一組什麼介面,如果我提供了一組介面給它,那麼這個代理物件就宣稱實現了該介面(多型),這樣我就能呼叫這組介面中的方法了
//h:一個InvocationHandler物件,表示的是當我這個動態代理物件在呼叫方法的時候,會關聯到哪一個InvocationHandler物件上