1. 程式人生 > 實用技巧 >代理模式(2):動態代理

代理模式(2):動態代理

一,動態代理介紹

  • 動態代理和靜態代理的角色都是一樣,靜態代理模式的代理類是我們提前寫好的,而動態代理的類是動態生成的,其實動態代理與靜態代理的本質一樣,最終程式執行時都需要生成一個代理物件例項,通過它來完成相關增強以及業務邏輯,只不過靜態代理需要硬編碼的方式指定,而動態代理支援執行時動態生成這種實現方式。動態生成的好處很明顯,在編碼時,代理邏輯與業務邏輯互相獨立,各不影響,沒有侵入,沒有耦合

二,與動態代理相關的兩個類

  • Interface InvocationHandler:該介面中僅定義了一個方法Object:invoke(Object obj,Method method,Object[] args)。在實際使用時,第一個引數obj一般是指代理類,method是被代理的方法,args為該方法的引數陣列。這個抽象方法在代理類中動態實現
  • Proxy:該類即為動態代理類,作用類似於上例中的ProxySubject,其中主要包含以下內容:
    Protected Proxy(InvocationHandler h):建構函式,估計用於給內部的h賦值。
    Static Class getProxyClass (ClassLoader loader,Class[] interfaces):獲得一個代理類,其中loader是類裝載器,interfaces是真實類所擁有的全部介面的陣列

三,程式碼實現動態代理

1,抽象角色

1 //抽象角色
2 public interface User {
3 
4     public void add();
5 
6 }

2,真實角色

1 //真實角色
2 public class UserImpl implements User {
3 
4     public void add() {
5         System.out.println("這是一個add方法");
6     }
7 
8 }

3,動態代理類生成的介面物件

 1 import java.lang.reflect.InvocationHandler;
 2 import java.lang.reflect.Method;
 3 import java.lang.reflect.Proxy;
 4 
 5 public class InvocationHandlerProxy  implements InvocationHandler {
 6 
 7     private User user;
 8 
 9     public void setUser(User user) {
10         this.user = user;
11     }
12 
13     //動態生成代理類
14     public Object getProxy(){
15         return Proxy.newProxyInstance(this.getClass().getClassLoader(),
16                 user.getClass().getInterfaces(),this);
17     }
18 
19     //proxy:代理類
20     //method:代理類的呼叫處理程式的方法 的物件
21     public Object invoke(Object proxy, Method method, Object[] args) throws Throwable {
22         show1();
23         Object invoke = method.invoke(user, args);
24         show2();
25         return invoke;
26     }
27 
28     public void show1(){
29         System.out.println("show方法1");
30     }
31 
32     public void show2(){
33         System.out.println("show方法2");
34     }
35 }

【注意InvocationHandler導包】

4,測試

 1 public class Test {
 2     public static void main(String[] args) {
 3 
 4         UserImpl userImpl = new UserImpl();
 5 
 6         InvocationHandlerProxy ihp = new InvocationHandlerProxy();
 7         ihp.setUser(userImpl);
 8 
 9         User proxy = (User) ihp.getProxy();
10 
11         proxy.add();
12     }
13 }

5,執行結果

四,總結

動態代理的好處

  • 可以使真實角色更加純粹,不用去關注一些公共的事情
  • 公共的業務由代理來完成,實現業務的分工
  • 公共業務的要擴充套件的話,可以更加集中和方便
  • 一個動態代理,一般代理一類的業務,一個動態代理可以代理多個類,代理介面