初步了解JDK動態代理
阿新 • • 發佈:2018-01-10
admin .get 自己 客戶 gpo ble log mic 其他
(2)創建被代理對象的類和接口
(3)通過Proxy.newProxyInstance()來創建代理類
(4)通過代理來調用被代理對象的方法
代理模式基本概念:
1.代理模式的作用:為其他對象提供一種以控制對方的訪問
在某種情況下,一個客戶不想或者不能直接引用另一個對象,代理可以在客戶端和目標對象之間起到中介的作用
代理的角色:
(1)抽象角色:聲明真實對象和代理對象的共同接口
(2)代理角色:代理對象內部含有真實對象的引用,從而可以操縱真實的對象,同時代理對象提供與真實對象相同的接口,以便在任何時候都能代替真實對象。代理對象可以在執行真實對象操作時附加其他的操作,相對於真實對象進行封裝。
(3)真實角色:代理對象所代理的真實角色,是我們要引用的對象
2.JDK動態代理
JDK動態代理可以為所有接口的實現類提供代理
動態代理開發步驟:
(1)創建一個實現接口InvocationHandler的類,它必須實現invoke方法
(2)創建被代理對象的類和接口
(3)通過Proxy.newProxyInstance()來創建代理類
(4)通過代理來調用被代理對象的方法
靜態代理demo:模擬通過代理租房
1 package proxydemo; 2 3 public interface HireHouse { 4 5 public void hire(); 6 }HireHouse
1 package proxydemo; 2 3 public class HireHouseImpl implements HireHouse { 4 5 @Override 6 publicHireHouseImplvoid hire() { 7 System.out.println("我要租房"); 8 9 } 10 11 }
代理類,實現HireHouse接口,持有代理對象(真實對象的引用)
1 package proxydemo; 2 3 public class HireHouseProxy implements HireHouse { 4 5 private HireHouse hh;//代理對象,持有真實對象的引用 6 7 8 public HireHouseProxy(HireHouse hh) {HireHouseProxy9 /*多態方式,接收接口的實現類對象,為靜態代理,缺點是,只能給租房這件事做代理, 10 *因為傳遞進來的是HireHouse這個接口的實現類對象 ,不能代理其他的事情*/ 11 super(); 12 this.hh = hh; 13 } 14 15 16 @Override 17 public void hire() { 18 System.out.println("收中介費");//代理做的事情 19 hh.hire();//真實對象租房 20 System.out.println("扣押金");//代理做的 21 22 } 23 24 }
調用代理類:
1 package proxydemo; 2 3 public class Client { 4 5 public static void main(String[] args) { 6 HireHouse proxyHire = new HireHouseProxy(new HireHouseImpl()); 7 System.out.print("---通過代理租房:"); 8 proxyHire.hire();//通過代理租房 9 System.out.print("---真實對象自己租房:"); 10 new HireHouseImpl().hire();//真實對象自己租房 11 12 } 13 }Client
動態代理demo:
1 package proxydemo.dynamic.proxy; 2 /** 3 * 真實對象和代理對象的共同接口,不僅僅能租房。 4 * @author Administrator 5 * 6 */ 7 public interface HireHouse { 8 9 public void hire(); 10 }
接口實現類:
1 package proxydemo.dynamic.proxy; 2 3 public class HireHouseImpl implements HireHouse { 4 5 @Override 6 public void hire() { 7 System.out.println("我要租房"); 8 } 9 }
代理類,實現InvocationHandler 接口
1 package proxydemo.dynamic.proxy; 2 3 import java.lang.reflect.InvocationHandler; 4 import java.lang.reflect.Method; 5 6 /** 7 * 實現InvocationHandler接口,通過反射去調用被代理的接口 8 * @author Administrator 9 * 10 */ 11 public class HireProxy implements InvocationHandler { 12 // 被代理的真實角色 13 private Object obj;// 真實角色,要給任何對象做代理,只能是持有Object類型的對象 14 15 public HireProxy(Object obj) { 16 super(); 17 this.obj = obj; 18 } 19 20 /** 21 * jdk動態代理,被代理對象必須實現接口 22 * 被代理的對象必然實現共同的Hire接口,那麽就有方法 23 * method:被代理的對象的接口中的方法,要調用方法,必須有對象,此處這個對象就是被代理對象,因此必須要指定被代理的對象 24 * args是被代理對象接口的方法的參數,調用proxy對象的method方法 25 */ 26 @Override 27 public Object invoke(Object proxy, Method method, Object[] args) 28 throws Throwable { 29 System.out.println("前置工作"); 30 // for (Object object : args) { 31 // System.out.print("invoke方法中的第三個參數:"+object +" ");//給list做代理時測試用 32 // } 33 Object invoke = method.invoke(obj, args); 34 System.out.println("\n後置工作"); 35 return invoke; 36 } 37 38 }
動態代理測試:
1 package proxydemo.dynamic.proxy; 2 3 import java.lang.reflect.Proxy; 4 import java.util.ArrayList; 5 import java.util.List; 6 7 public class Client { 8 9 public static void main(String[] args) { 10 // 創建被代理的接口實現類對象 11 HireHouseImpl hhi = new HireHouseImpl(); 12 //創建代理對象:第一個參數是被代理的對象的類加載器,第二個是被代理對象的類的所有接口,第三個參數是自定義代理類的角色 13 HireHouse hh = 14 (HireHouse)Proxy.newProxyInstance(hhi.getClass().getClassLoader(), 15 hhi.getClass().getInterfaces(), new HireProxy(hhi)); 16 hh.hire(); 17 18 // 給list做代理 19 // List list = new ArrayList(); 20 // List hh1 = (List) Proxy.newProxyInstance(list.getClass() 21 // .getClassLoader(), list.getClass().getInterfaces(), 22 // new HireProxy(list)); 23 // hh1.add("張三"); 24 // hh1.get(0);//被代理對象的所有方法都被代理了 25 26 } 27 }
初步了解JDK動態代理