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


    作者:雨夜偷牛的人
    链接: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. 解耦,通过参数就可以判断真实类,不需要事先实例化,更加灵活多变。
  • 相关阅读:
    【异常】org.mybatis.spring.MyBatisSystemException: nested exception is org.apache.ibatis.binding.BindingException: Parameter '**' not found.的解决办法
    java如何进行字符串拼接?
    poj2352消防站
    NOIP第7场模拟赛题解
    转载:
    usaco 2010年3月银组题解
    Js 向json对象中添加新元素
    List<T>中 GetRange (int index, int count)的使用
    C# string格式的日期时间字符串转为DateTime类型
    C# DataTable转List<T>--利用反射
  • 原文地址:https://www.cnblogs.com/yadongliang/p/8327387.html
Copyright © 2020-2023  润新知