1. 程式人生 > >Java設計模式之代理模式的動態代理

Java設計模式之代理模式的動態代理

前言

什麼是動態代理呢?動態代理指的是在實現階段不需要關心代理誰,而是在執行階段才指定哪一個物件。

 

動態代理示例

首先要介紹一下JDK提供的一個動態代理介面 InvocationHandler。這個介面的用途在於對代理類的方法進行代理,我們先實現InvocationHandler介面:

 1 public class ConsumerHandler implements InvocationHandler {
 2 
 3     private Object proxiedInstance = null;
 4 
 5     public ConsumerHandler(Object proxiedInstance) {
6 this.proxiedInstance = proxiedInstance; 7 } 8 9 @Override 10 public Object invoke(Object proxy, Method method, Object[] args) throws Throwable { 11 12 Object proxyInstance = method.invoke(this.proxiedInstance, args); 13 return proxyInstance; 14 }
15 }

第3行:宣告被代理的物件例項。

第5行:構造行數被代理物件作為形式引數。

第10行-14行:呼叫被代理的方法。

 

消費者抽象介面和消費者真實角色都沒有改動,程式碼如下圖所示:

1 public interface IConsumer {
2 
3     public void login(String name, String password);
4 
5     public void order();
6 
7     public void pay();
8 
9 }
 1 public class RealConsumer implements
IConsumer { 2 3 private String name = null; 4 5 public RealConsumer(String name){ 6 this.name = name; 7 } 8 9 @Override 10 public void login(String name, String password) { 11 12 System.out.println("登入使用者["+name+"]登陸成功"); 13 } 14 15 @Override 16 public void order() { 17 18 System.out.println("登入賬號:"+ this.name +"生成訂單成功"); 19 20 } 21 22 @Override 23 public void pay() { 24 25 System.out.println("登入賬號:"+ this.name +"訂單支付成功"); 26 27 } 28 29 }

OK。這個都沒什麼問題,最後我們再看看一下動態代理的場景類:

 1 public class Client {
 2 
 3     public static void main(String[] args) {
 4         IConsumer consumer = new RealConsumer("抒盡");
 5 
 6         ConsumerHandler consumerHandler = new ConsumerHandler(consumer);
 7 
 8         ClassLoader classLoader = consumer.getClass().getClassLoader();
 9 
10         Object o = Proxy.newProxyInstance(classLoader, new Class[]{IConsumer.class}, consumerHandler);
11         IConsumer proxy = (IConsumer)o;
12 
13         proxy.login("shujin", "123456");
14         proxy.order();
15         proxy.pay();
16     }
17 }

第4行,定義一個真實消費者[抒盡]

第6行,定義一個handler

第8行,獲取真實角色的類載入器

第10行-11行,動態產生一個代理者

第13行-15行,使用代理者來訪問。

 

使用動態代理,我們並沒有手工去建立一個代理類,更加沒有代理類實現抽象介面。這就是動態代理的強大功能,如果我們需要變更需求,只需要修改動態代理實現類即可。

如果使用InvovationHandler實現動態代理。要產生某個類的代理,這個類必須要有介面