1. 程式人生 > >初步了解JDK動態代理

初步了解JDK動態代理

admin .get 自己 客戶 gpo ble log mic 其他

代理模式基本概念:
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     public
void hire() { 7 System.out.println("我要租房"); 8 9 } 10 11 }
HireHouseImpl

代理類,實現HireHouse接口,持有代理對象(真實對象的引用)

技術分享圖片
 1 package proxydemo;
 2 
 3 public class HireHouseProxy implements HireHouse {
 4 
 5     private HireHouse hh;//代理對象,持有真實對象的引用
 6     
 7     
 8     public HireHouseProxy(HireHouse hh) {
9 /*多態方式,接收接口的實現類對象,為靜態代理,缺點是,只能給租房這件事做代理, 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 }
HireHouseProxy

調用代理類:

技術分享圖片
 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動態代理