• 代理模式


    代理模式:某个代理对象和真实对象都实现同一个接口,代理对象有真实对象的引用,实现的业务还是有真实对象来完成,但是代理对象可以在实现业务加一些别的代码。

    静态代理

    public interface BuyHouse {
    
        void buyHouse();
    }

    定义一个接口

    public class BuyHouseImpl implements BuyHouse{
    
        @Override
        public void buyHouse() {
            System.out.println("买房子");
        }
    }
    public class BuyHouseProxy implements BuyHouse{
    
        private BuyHouse buyHouse;
    
        public BuyHouseProxy(BuyHouse buyHouse){
            this.buyHouse = buyHouse;
        }
        @Override
        public void buyHouse() {
            System.out.println("买房前的准备");
            buyHouse.buyHouse();
            System.out.println("买完后装修");
        }
    }

    代理类

    动态代理

    public class DynamicBuyHouse implements InvocationHandler{
    
        private  BuyHouse buyHouse;
    
        public DynamicBuyHouse(BuyHouse buyHouse){
            this.buyHouse = buyHouse;
        }
    
        @Override
        public Object invoke(Object proxy, Method method, Object[] args) throws Throwable {
            System.out.println("买房前准备");
            method.invoke(buyHouse,args);
            System.out.println("买房后装修");
            return null;
        }
    }
    public class Test {
        public static void main(String[] args) {
            InvocationHandler handler = new DynamicBuyHouse(new BuyHouseImpl());
            BuyHouse house = (BuyHouse) Proxy.newProxyInstance(BuyHouse.class.getClassLoader(),new Class<?>[]{BuyHouse.class},handler);
            house.buyHouse();
        }
    }
    import java.lang.reflect.InvocationHandler;
    import java.lang.reflect.Method;
    import java.lang.reflect.Proxy;
    import java.lang.reflect.UndeclaredThrowableException;
    import proxy.Person;
    
    public final class $Proxy0 extends Proxy implements Person
    {
      private static Method m1;
      private static Method m2;
      private static Method m3;
      private static Method m0;
      
      /**
      *注意这里是生成代理类的构造方法,方法参数为InvocationHandler类型,看到这,是不是就有点明白
      *为何代理对象调用方法都是执行InvocationHandler中的invoke方法,而InvocationHandler又持有一个
      *被代理对象的实例,不禁会想难道是....? 没错,就是你想的那样。
      *
      *super(paramInvocationHandler),是调用父类Proxy的构造方法。
      *父类持有:protected InvocationHandler h;
      *Proxy构造方法:
      *    protected Proxy(InvocationHandler h) {
      *         Objects.requireNonNull(h);
      *         this.h = h;
      *     }
      *
      */
      public $Proxy0(InvocationHandler paramInvocationHandler)
        throws 
      {
        super(paramInvocationHandler);
      }
      
      //这个静态块本来是在最后的,我把它拿到前面来,方便描述
       static
      {
        try
        {
          //看看这儿静态块儿里面有什么,是不是找到了giveMoney方法。请记住giveMoney通过反射得到的名字m3,其他的先不管
          m1 = Class.forName("java.lang.Object").getMethod("equals", new Class[] { Class.forName("java.lang.Object") });
          m2 = Class.forName("java.lang.Object").getMethod("toString", new Class[0]);
          m3 = Class.forName("proxy.Person").getMethod("giveMoney", new Class[0]);
          m0 = Class.forName("java.lang.Object").getMethod("hashCode", new Class[0]);
          return;
        }
        catch (NoSuchMethodException localNoSuchMethodException)
        {
          throw new NoSuchMethodError(localNoSuchMethodException.getMessage());
        }
        catch (ClassNotFoundException localClassNotFoundException)
        {
          throw new NoClassDefFoundError(localClassNotFoundException.getMessage());
        }
      }
     
      /**
      * 
      *这里调用代理对象的giveMoney方法,直接就调用了InvocationHandler中的invoke方法,并把m3传了进去。
      *this.h.invoke(this, m3, null);这里简单,明了。
      *来,再想想,代理对象持有一个InvocationHandler对象,InvocationHandler对象持有一个被代理的对象,
      *再联系到InvacationHandler中的invoke方法。嗯,就是这样。
      */
      public final void giveMoney()
        throws 
      {
        try
        {
          this.h.invoke(this, m3, null);
          return;
        }
        catch (Error|RuntimeException localError)
        {
          throw localError;
        }
        catch (Throwable localThrowable)
        {
          throw new UndeclaredThrowableException(localThrowable);
        }
      }
    
      //注意,这里为了节省篇幅,省去了toString,hashCode、equals方法的内容。原理和giveMoney方法一毛一样。
    
    }

    这就是那个动态生成的类,可以看出当他调用giveMoney()时,会调用父类的super.h.invoke(); h就是你传入的那个handler类,最后就是调用了你写的那个handler里面的invoke()方法,method也就是proxy调用的方法.

  • 相关阅读:
    美赛 LaTeX 急救指南
    切比雪夫定理的证明
    【持续更新】一个简洁、易用的美赛 LaTeX 模板: easymcm
    一个形式较精细的 Strling 公式的证明
    数学分析的主线,高等数学的一切:连续函数与“有理”分析
    一个自己稍作修改了的美赛论文 LaTeX 模板
    有关几个特殊命题的证明
    实数系与实数定理(下)
    实数系与实数定理(上)
    Office365完整离线安装包下载及自定义安装教程
  • 原文地址:https://www.cnblogs.com/lzh66/p/13288898.html
Copyright © 2020-2023  润新知