反射(五)之动态代理的作用

作者:雨夜偷牛的人
链接:https://www.zhihu.com/question/20794107/answer/23330381
来源:知乎
著作权归作者所有。商业转载请联系作者获得授权,非商业转载请注明出处。

关于动态代理设计模式很可能题主就在不知不觉中使用了,例如Spring中的AOP,Struts2中的拦截器等。

先来看静态代理模式代码:
 1 package test;
 2 
 3 public interface Subject   
 4 {   
 5   public void doSomething();   
 6 }
 7 
 8 package test;
 9 
10 public class RealSubject implements Subject   
11 {   
12   public void doSomething()   
13   {   
14     System.out.println( "call doSomething()" );   
15   }   
16 }  
17 
18 package test;
19 
20 public class SubjectProxy implements Subject
21 {
22   Subject subimpl = new RealSubject();
23   public void doSomething()
24   {
25      subimpl.doSomething();
26   }
27 }
28 
29 package test;
30 
31 public class TestProxy 
32 {
33    public static void main(String args[])
34    {
35        Subject sub = new SubjectProxy();
36        sub.doSomething();
37    }
38 }

刚开始我会觉得SubjectProxy定义出来纯属多余,直接实例化实现类完成操作不就结了吗?后来随着业务庞大,你就会知道,实现proxy类对真实类的封装对于粒度的控制有着重要的意义。但是静态代理这个模式本身有个大问题,如果类方法数量越来越多的时候,代理类的代码量是十分庞大的。所以引入动态代理来解决此类问题。

先看代码:
 1 package test;
 2 
 3 public interface Subject   
 4 {   
 5   public void doSomething();   
 6 }
 7 
 8 package test;
 9 
10 public class RealSubject implements Subject   
11 {   
12   public void doSomething()   
13   {   
14     System.out.println( "call doSomething()" );   
15   }   
16 }  
17 
18 package test;
19 
20 import java.lang.reflect.InvocationHandler;  
21 import java.lang.reflect.Method;  
22 import java.lang.reflect.Proxy;  
23 
24 public class ProxyHandler implements InvocationHandler
25 {
26     private Object tar;
27 
28     //绑定委托对象,并返回代理类
29     public Object bind(Object tar)
30     {
31         this.tar = tar;
32         //绑定该类实现的所有接口,取得代理类 
33         return Proxy.newProxyInstance(tar.getClass().getClassLoader(),
34                                       tar.getClass().getInterfaces(),
35                                       this);
36     }    
37 
38     public Object invoke(Object proxy , Method method , Object[] args)throws Throwable
39     {
40         Object result = null;
41         //这里就可以进行所谓的AOP编程了
42         //在调用具体函数方法前,执行功能处理
43         result = method.invoke(tar,args);
44         //在调用具体函数方法后,执行功能处理
45         return result;
46     }
47 }
48 
49 public class TestProxy
50 {
51     public static void main(String args[])
52     {
53            ProxyHandler proxy = new ProxyHandler();
54            //绑定该类实现的所有接口
55            Subject sub = (Subject) proxy.bind(new RealSubject());
56            sub.doSomething();
57     }
58 }

看完代码,现在我来回答,动态代理的作用是什么:

  1. Proxy类的代码量被固定下来,不会因为业务的逐渐庞大而庞大;
  2. 可以实现AOP编程,实际上静态代理也可以实现,总的来说,AOP可以算作是代理模式的一个典型应用;
  3. 解耦,通过参数就可以判断真实类,不需要事先实例化,更加灵活多变。
posted @ 2018-01-22 07:55  习惯沉淀  阅读(1536)  评论(0编辑  收藏  举报