標籤:invoke 分代 handler aop 代理服務 方法 void htable 需要
java.lang.reflect包下提供了一個Proxy類和InvocationHandler介面,用於產生動態代理類和動態代理對象。
一、使用Proxy、InvocationHandler建立動態代理
這裡要注意,在java.net包下也有一個Proxy類,不過這個類是用於設定Proxy 伺服器的,莫混淆。。
Proxy提供了如下兩個方法建立動態代理類和動態代理執行個體:
實際上即使採用第一種方法建立動態代理類,如果程式需要通過該代理類來建立對象,依然需要傳入一個InvocationHandler對象,也就是說,系統產生的每個代理對象都有一個與之關聯的InvocationHandler對象。
public class ProxyTest { public static void main(String[] args){ MyInvocationHandler invocationHandler = new MyInvocationHandler(); invocationHandler.setTarget(new Hero()); Person hero= (Person) Proxy.newProxyInstance(Hero.class.getClassLoader(),Hero.class.getInterfaces(),invocationHandler);// hero.fight();// hero.laugh(); hero.sayHello("Tom"); hero.work(); }}interface Person{ void work(); void sayHello(String name);}interface FightAble{ void fight();}class Hero implements Person,FightAble{ @Override public void fight() { System.out.println("hero fight"); } @Override public void work() { System.out.println("hero work"); } @Override public void sayHello(String name) { System.out.println("hello "+name); } public void laugh(){ System.out.println("hero laugh"); }}class MyInvocationHandler implements InvocationHandler{ private Object target; public void setTarget(Object target) { this.target = target; } @Override public Object invoke(Object proxy, Method method, Object[] args) throws Throwable { System.out.println("-------正在執行的方法:"+method); if(args != null){ System.out.println("下面是執行該方法傳入的實參:"); for (Object val : args){ System.out.println(val); } } else { System.out.println("調用的方法沒有實參"); method.invoke(target); } return null; }}
注意,java動態代理產生的對象一定要用介面引用指向之,這是由於java的動態代理實際上時使用傳入的介面類型建立了新的類,所以在上面代碼中不可以用Hero類型指向建立的對象,只能由Person或FightAble類型指向之。看源碼就可以發現這一點。
二、AOP代理
AOP(面向切面編程),的一種實現方式就是使用java動態代理。
在上面的代碼中實際上已經實現了AOP,對所有代理對象的無實參方法,在執行方法body之前都先執行System.out.println("調用的方法沒有實參");只不過這些代碼寫在了InvocationHandler中,而像Spring之類的架構會把這一部分代碼用設計模式解耦出來,但本質上還是這樣子的原理。
java核心學習(四十) 使用反射產生JDK動態代理