Spring2.5學習4.2_Proxy實現動態代理(目標類實現隨意接口)
阿新 • • 發佈:2017-05-13
靈活 iss sta blank 輸入 font ima tar ons
[java] view plaincopy 在main方法中調用proTest對象的bind綁定方法將一個實現類與一個動態代理進行綁定,動態代理主要由下面代碼來實現
結果:
靜態代理的缺點是在代理類中綁定了固定的接口,不利於擴展,動態代理則不然,通過動態代理能夠對不論什麽實現某一接口的類進行功能性增強。
在java中動態代理由InvocationHander來實現。
HelloInterface接口
[java] view plaincopy
- package proxy;
- public interface HelloInterface {
- public void sayHello();
- }
[java] view plaincopy
-
package
- public class HelloInterfaceImpl implements HelloInterface {
- @Override
- public void sayHello() {
- System.out.println("Hello xianjj");
- }
- }
proTest類實現了InvocationHandler類
package proxy; import java.lang.reflect.InvocationHandler; import java.lang.reflect.Method; import java.lang.reflect.Proxy; // 實現InvocationHandler接口 public class proTest implements InvocationHandler { Object anyObject; // 申明bind方法 public Object bind (Object anyObject){ this.anyObject = anyObject; return Proxy.newProxyInstance(anyObject.getClass().getClassLoader(), anyObject.getClass().getInterfaces(), this); } // 重寫invoke方法 @Override public Object invoke(Object arg0, Method arg1, Object[] args) throws Throwable { Object returnObject = null; System.out.println("動態代理開始"); returnObject = arg1.invoke(anyObject, args); System.out.println("動態代理結束"); return returnObject; } public static void main(String[] args) { proTest proTest = new proTest(); HelloInterface helloInterfaceReturn = (HelloInterface)proTest.bind(new HelloInterfaceImpl()); helloInterfaceReturn.sayHello(); } }
Proxy.newProxyInstance(anyObject.getClass().getClassLoader(), anyObject.getClass().getInterfaces(), this);將輸入的anyObject對象與接口進行動態關聯,這樣就能夠避免靜態接口固定的缺陷了,動態代理由原來的靜態代理面向接口轉向動態代理面向實現類,這樣設計的出發點不是對接口。而是動態的取的接口,軟件的靈活性大大的提高。
當調用被代理的HelloInterfaceImpl類實例的方法時,系統將轉到包括代理類proTest的InvocationHandler的invoke方法中運行對應的代碼。動態代理的過程結束。
public class proTest implements InvocationHandler類不在服務於某一個接口,靜態代理和動態代理都是針對於sayHello()方法進行增強。不支持field字段級的增強。Spring覺得那已經在破壞面向對象編程的結構,所以支持方法的增強是再合適不的,並且與Spring的其它模塊進行整合開發時會更有集中性。
結果:
Spring2.5學習4.2_Proxy實現動態代理(目標類實現隨意接口)