zoukankan      html  css  js  c++  java
  • 代理模式

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

    静态代理

    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调用的方法.

  • 相关阅读:
    ES6 语法
    使用过滤器进行跨域
    java读取资源文件(Properties)
    跨域
    java提取(获取)博客信息(内容)
    SSM命名规范框架
    学校管理系统设计java(数据库、源码、演讲内容、ppt等)
    学校管理系统C#(数据库、源码、演讲内容、ppt等)
    vue快速使用
    故障排除:无法启动、访问或连接到 Azure 虚拟机上运行的应用程序
  • 原文地址:https://www.cnblogs.com/lzh66/p/13288898.html
Copyright © 2011-2022 走看看