本文目錄一覽:
java動態代理是什麼
import java.lang.reflect.Proxy;
A. 創建一個實現介面InvocationHandler的類,他必須實現invoke方法
B. 創建被代理的類以及介面。
C. 通過Proxy的靜態方法newProxyInstance(ClassLoader loader,Class【】interfaces,InvocationHandler handler)創建一個代理
D. 通過代理調用方法。
java動態代理:是在運行是生成的class對象,在生成時必須提供一組或一個interface給它,然後該class就宣稱它實現了這些interface。你當然可以把該class的實例當做這些interface中的任何一個來用,當然,這個DynamicProxy其實就是一個Proxy,他不會替你做實質性的工作,在生成它的實例時你必須提供一個handler,由它接管實際的工作。因此,DynamicProxy必須實現InvocationHandler介面。
5) 一個動態代理了和一個InvocationHandler 實現關聯的。每一個動態代理實例的調用都要通過InvocationHandler介面的handler(調用處理器)來調用,動態代理不做任何執行操作,只是在創建動態代理時,把要實現的介面和handler關聯,動態代理要幫助被代理執行的任務,要轉交給handler來執行。其實就是調用invoke方法。
JAVA動態代理設計原理及如何實現
ava動態代理機制的出現,使得Java開發人員不用手工編寫代理類,只要簡單地制定一組介面及委託類對象,便能動態地獲得代理類。代理類會負責將所有的方法調用分配到委託對象上反射執行,配置執行過程中,開發人員還可以進行修改
代理設計模式
代理是一種常用的設計模式,其目的就是為其他對象提供一個代理以控制對某個對象的訪問。代理類負責為委託類預處理消息、過濾消息並轉發消息,以及進行消息被委託類執行後的後續處理。
1.
為了保持行為的一致性,代理類和委託類通常會實現相同的介面
2.
引入代理能夠控制對委託對象的直接訪問,可以很好的隱藏和保護委託對象,也更加具有靈活性
相關的類和介面
要了解
Java
動態代理的機制,首先需要了解以下相關的類或介面:
1.
java.lang.reflect.Proxy:這是
Java
動態代理機制的主類,它提供了一組靜態方法來為一組介面動態地生成代理類及其對象
2.
java.lang.reflect.InvocationHandler:這是調用處理器介面,它自定義了一個invoke方法,用於幾種處理在動態代理類對象上的方法調用。通常在該方法中實現對委託類的代理訪問。
3.
java.lang.ClassLoader:Proxy
靜態方法生成動態代理類同樣需要通過類裝載器來進行裝載才能使用,它與普通類的唯一區別就是其位元組碼是由
JVM
在運行時動態生成的而非預存在於任何一個.class
文件中。
代理機制及其特點
首先讓我們來了解一下如何使用
Java
動態代理。具體有如下四步驟:
1.
通過實現
InvocationHandler
介面創建自己的調用處理器;
2.
通過為
Proxy
類指定
ClassLoader
對象和一組
interface
來創建動態代理類;
3.
通過反射機制獲得動態代理類的構造函數,其唯一參數類型是調用處理器介面類型;
4.
通過構造函數創建動態代理類實例,構造時調用處理器對象作為參數被傳入。
java中動態代理的詳細解釋 最好能通俗易懂
在目前的Java開發包中包含了對動態代理的支持,但是其實現只支持對介面的的實現。
其實現主要通過是java.lang.reflect.Proxy類和java.lang.reflect.InvocationHandler介面。
Proxy類主要用來獲取動態代理對象,InvocationHandler介面用來約束調用者實現,如下,HelloWorld介面定義的業務方法,HelloWorldImpl是HelloWorld介面的實現,HelloWorldHandler是 InvocationHandler介面實現。代碼如下:
業務介面:
public interface HelloWorld {
void sayHelloWorld() ;
}
業務介面實現:
public class HelloWorldImpl implements HelloWorld {
public void sayHelloWorld() {
System.out.println(“Hello World!”);
}
}
InvocationHandler實現,需要在介面方法調用前後加入一部份處理工作,這裡僅僅在方法調用前後向後台輸出兩句字元串,其代碼如下:
import java.lang.reflect.InvocationHandler;
import java.lang.reflect.Method;
public class HelloWorldHandler implements InvocationHandler {
//要代理的原始對象
private Object objOriginal;
/**
* 構造函數。
* @param obj 要代理的原始對象。
*/
public HelloWorldHandler(Object obj) {
this.objOriginal = obj ;
}
public Object invoke(Object proxy, Method method, Object[] args)
throws Throwable {
Object result ;
//方法調用之前
doBefore();
//調用原始對象的方法
result = method.invoke(this.objOriginal ,args);
//方法調用之後
doAfter();
return result ;
}
private void doBefore() {
System.out.println(“before method invoke!”);
}
private void doAfter() {
System.out.println(“after method invoke!”);
}
}
測試代碼:
import java.lang.reflect.InvocationHandler;
import java.lang.reflect.Proxy;
public class Test {
public static void main(String[] args) {
HelloWorld hw = new HelloWorldImpl();
InvocationHandler handler = new HelloWorldHandler(hw);
HelloWorld proxy = (HelloWorld) Proxy.newProxyInstance(
hw.getClass().getClassLoader(),
hw.getClass().getInterfaces(),
handler);
proxy.sayHelloWorld();
}
}
Ø 首先獲取一個業務介面的實現對象;
Ø 獲取一個InvocationHandler實現,此處是HelloWorldHandler對象;
Ø 創建動態代理對象;
Ø 通過動態代理對象調用sayHelloWorld()方法,此時會在原始對象HelloWorldImpl. sayHelloWorld()方法前後輸出兩句字元串。
運行測試類輸出如下:
before method invoke!
Hello World!
after method invoke!
此處Test類中的方法調用代碼比較多,在我們的實際應用中可以通過配置文件來來簡化客戶端的調用實現。另外也可以通過動態代理來實現簡單的AOP。
參考資料:
原創文章,作者:KVHKA,如若轉載,請註明出處:https://www.506064.com/zh-tw/n/313755.html