標籤:eth 方法 body 過程 ack nts int 使用 system
1.動態代理概念
動態代理是程式在運行過程中自動建立一個代理對象代替被代理的對象去執行相應的操作。在Java的動態代理機制中,有兩個重要的類或介面,一個是InvocationHandler介面,另一個是Proxy類,這兩個是實現動態代理必須用到的。
2.動態代理的實現
(1)建立一個類實現InvocationHandler介面,並實現invoke方法。每個動態代理類都必須實現InvocationHandler介面,並在invoke方法中調用被代理的真實對象的方法及在其前後添加相應的方法和邏輯實現代理的功能。
(2)使用Proxy類的newProxyInstance方法建立一個代理對象,並關聯到一個InvocationHandler對象
實現(1)、(2)步之後,當我們調用代理對象的方法時,該方法調用就會被轉化為代理對象關聯到的InvocationHandler對象的invoke方法調用。
我們首先看一下InvocationHandler介面的invoke方法
public Object invoke(Object proxy, Method method, Object[] args) throws Throwable {}
這個方法一共接收3個參數,含義分別為:
proxy:代理對象
method:代理對象調用的方法的Method對象
args:代理對象調用方法時傳入的參數
再看一下Proxy類,Proxy類提供了許多的方法,但是我們用的最多的就是 newProxyInstance 這個方法
public static Object newProxyInstance(ClassLoader loader, Class<?>[] interfaces, InvocationHandler handler){}
這個方法的作用就是建立一個代理對象,並關聯一個InvocationHandler對象,其接收的3個參數含義為:
loader:定義了由哪個ClassLoader來載入建立的代理對象
interfaces:表示我們將給代理對象提供一組什麼介面,如果我們提供了一組介面,那麼這個代理對象就宣稱實現了該介面(多態),這樣我們就能調用這組介面中的方法了
handler:表示代理對象關聯的InvocationHandler對象
-------------------Talk is cheap,show me the code----------------
定義一個介面,真實對象和代理對象都實現該介面
package com.jiangwangxiang.dynamicProxy;
public interface IService {
public Object execute();
}
真實對象的類
package com.jiangwangxiang.dynamicProxy;
public class MajorService implements IService{
@Override
public Object execute() {
System.out.println("主業務執行...");
return null;
}
}
建立動態代理類
package com.jiangwangxiang.dynamicProxy;
import java.lang.reflect.InvocationHandler;
import java.lang.reflect.Method;
//建立一個代理類,實現InvocationHandler介面
public class LogProxy implements InvocationHandler {
//被代理真實對象
private MajorService target;
public LogProxy(MajorService target) {
this.target = target;
}
@Override
public Object invoke(Object proxy, Method method, Object[] args) throws Throwable {
// 被代理的真實對象的方法調用前的方法邏輯
System.out.println("----主業務執行前處理----");
// 調用被代理的真實對象的方法
Object result = target.execute();
// 被代理的真實對象的方法調用後的方法邏輯
System.out.println("----主業務執行後處理----");
// 返回被代理對象的方法傳回值,一般代理對象都只在被代理對象的方法執行前後添加一些邏輯,不影響方法執行結果
return result;
}
}
測試類別
package com.jiangwangxiang.dynamicProxy;
import java.lang.reflect.Proxy;
//動態代理測試類別
public class DynamicProxyTest {
public static void main(String[] args) {
//建立被代理的真實對象
MajorService majorService = new MajorService();
//建立InvocationHandler對象,傳入被代理的真實對象
LogProxy handler = new LogProxy(majorService);
//建立代理對象,並與InvocationHandler對象關聯
IService serviceProxy = (IService) Proxy.newProxyInstance(handler.getClass().getClassLoader(),
majorService.getClass().getInterfaces(), handler);
//調用代理對象的方法,該方法調用將會被轉化為代理對象關聯的InvocationHandler對象的invoke方法調用
serviceProxy.execute();
}
}
-------------------------
輸出結果為:
----主業務執行前處理----
主業務執行...
----主業務執行後處理----
Java動態代理