標籤:動態代理
JAVA動態代理初解
代理模式:簡單來講就是一件事情由另外的對象去代為操作。最簡單的執行個體,寫了個介面,一個類去實現這個介面中的方法,但是突然有一天要對方法增加比如日誌記錄,存取權限等功能時,那麼我們可以寫另外一個類去實現介面中的方法,然後增加比如日誌記錄,存取權限的代碼,引用原類中的方法完成封裝。但是這樣會存在一個問題,就是系統中的類的數量會擴大,導致系統啟動並執行記憶體佔用越來越大(新的類與原來的類都會佔用記憶體),所以JAVA提供了針對介面的動態代理模式。為什麼叫動態了,因為其用了JAVA反射機制,通過反射介面的class對象來封裝產生新的class對象,並通過系統提供的InvocationHandler介面來增加對原方法的功能的擴充。
比如:Proxy代理對象類中的newProxyInstance,其用來建立代理對象。
public static Object newProxyInstance(ClassLoader loader,
Class<?>[] interfaces,
InvocationHandler h)
throws IllegalArgumentException
原始碼中:
final InvocationHandler ih = h;
final Class<?>[] intfs = interfaces.clone();//可以看到首先對介面進行複製
Class<?> cl = getProxyClass0(loader, intfs);//接著將介面class與類載入器一起封裝產生新的class對象
final Constructor<?> cons = cl.getConstructor(constructorParams);//根據參數得到構造方法
而構造方法中的參數constructorParams,為一個InvocationHandler.class
private static final Class<?>[] constructorParams = { InvocationHandler.class };
最後返回return newInstance(cons, ih);
換句話說,代理對象就是通過封裝原介面,並擴充一個新介面,功能的新增實現在新介面的invoke()
public Object invoke(Object proxy, Method method, Object[] args)
throws Throwable;
即可以在這個方法中添加新的功能代碼,然後通過原類的Method來調用原方法。
Object obj=method.invoke(test, args);test:被代理的類,args:方法參數
這樣當Proxy調用newProxyInstance組建代理程式對象,調用被代理類中的方法時,會進入到InvocationHandler介面實作類別中的invoke()方法去增加新功能,調用被代理類的原方法。
JAVA動態代理初解