Java動態代理簡單例項:老闆與祕書
Java動態代理是Java中比較晦澀難懂的一個部分,雖然看了一些別人的部落格之後覺得自己大體明白了,但是事非經過不知難,自己寫的時候卻產生了諸多疑問。
本文用盡可能簡單的例子來說明Java動態代理的機制。
例子共四個部分:
1. ReadFile介面(批改檔案)
2. Boss類,委託類,能夠批改檔案
3. Secretary類,沒有實現ReadFile介面,用Secretary可建立代理類,“代理”Boss批改檔案(創建出來的代理類物件就是main函式中的secretary1)
4. Main類
1. ReadFile介面
public interface ReadFile { public void read(); }
2. Boss類,實現了ReadFile介面,可以批改檔案
public class Boss implements ReadFile {
@Override
public void read() {
System.out.println("I'm reading files.");
}
}
3. Secretary類,不是代理類,但利用這個類能創建出代理類
import java.lang.reflect.InvocationHandler; import java.lang.reflect.Method; public class Secretary implements InvocationHandler { private Object object; public Secretary(Object object) { this.object = object; } @Override public Object invoke(Object proxy, Method method, Object[] args) throws Throwable { System.out.println("I'm secretary."); Object result = method.invoke(object, args); return result; } }
Secretary類中有一個變數object用來存boss物件,因為接下來Secretary要代理Boss做的事,因此先要把boss物件先儲存起來。
Secretary類如果想代理Boss做的事,即呼叫Boss類的方法,必須實現InvocationHandler,過載invoke方法,然後在invoke函式中呼叫Boss類的方法。
我們看到invoke函式中有一句method.invoke(object, args),代理類就是用這種方式呼叫委託類的方法。
4. Main類
整個函式的執行流程如下:import java.lang.reflect.Proxy; public class Main { public static void main(String[] args) { ReadFile boss = new Boss(); InvocationHandler handler = new Secretary(boss); ReadFile secretary = (ReadFile) Proxy.newProxyInstance( boss.getClass().getClassLoader(), boss.getClass().getInterfaces(), handler); secretary.read(); } }
先是建立了一個boss物件,
然後建立一個handler物件,
然後利用handler構造出一個能呼叫boss方法的物件secretary,這個secretary就是代理類物件
執行最後一句時,代理類的public Object invoke(...)方法被呼叫,代理類在此處呼叫委託類的方法,method.invoke()先列印I'm secretary,再呼叫boss物件的方法read()。
secretary每呼叫一次read()時都會執行public Object invoke(...),顯而易見傳入的第二個引數method即read(),第三個引數args即傳入read()的引數(這裡沒有)。
實現了InvocationHandler的Secretary類並不能直接呼叫委託類的方法,handler物件只是一個handler,只有當handler物件用newProxyInstance方法包裹成secretary物件後,才具有呼叫boss方法的能力。
既然說secretary是由handler包裹而成的,那secretary是什麼型別的呢?
System.out.println(secretary.getClass().getName());
型別是$Proxy0
如果文章中存在問題請及時指正。