欢迎来到Vincentyw的博客

该来的终究会来,该走的也一定会离开。凡事都存在前因后果,因缘成熟了,果报便产生了,无法阻挡。
但是发生过了就会消失,有来就有走,一切都是过客,把握自己当下的因缘,承担起自己该承担的责任,做好眼前该做的事情,做的时候尽全力,过去便放下,放下即自在。

设计模式之代理模式

Proxy(代理模式)

一、代理模式简介

在代理模式(Proxy Pattern)中,一个类代表另一个类的功能。这种类型的设计模式属于结构型模式。

在代理模式中,我们创建具有现有对象的对象,以便向外界提供功能接口。

核心:

  • 1、通过代理,控制对对象的访问。
  • 2、可以详细控制访问某个(某类)对象的方法,在调用这个方法前做前置处理,调用这个方法后 做后置处理

二、代理模式优缺点比较

优点:

  • 1、职责清晰。
  • 2、高扩展、智能化。

缺点:

  • 1、请求的处理速度变慢
  • 2、实现代理模式需要额外的工作,有些代理模式的实现非常复杂

使用场景:

  • 1、安全代理:屏蔽对真实角色的直接访问
  • 2、远程代理:通过代理类处理远程方法调用(RMI)
  • 3、延迟加载:先加载轻量级的代理对象,真正需要再加载真实对象

注意事项:1、和适配器模式的区别:适配器模式主要改变所考虑对象的接口,而代理模式不能改变所代理类的接口。 2、和装饰器模式的区别:装饰器模式为了增强功能,而代理模式是为了加以控制。

三、静态代理UML类图

四、静态代理实现

  步骤1:创建接口

public interface Movable {
    void move();
}

 步骤2:创建实现接口的实体类

public class AudiCar implements Movable{

    @Override
    public void move() {
        System.out.println("AudiCar is moving cacaca....................");
    }
}

步骤3:创建实现接口的代理类

public class AudiCarTimeProxy implements Movable {
    
    private Movable thing;
    
    public AudiCarTimeProxy(Movable thing) {
        this.thing = thing;
    }
    
    @Override
    public void move() {
        long start = System.currentTimeMillis();
        System.out.println("AudiCarTimeProxy move start ");
        try {
            Thread.sleep(new Random().nextInt(1000));
        } catch (InterruptedException e) {
        System.out.println("run exception");
        }
        thing.move();
        long end  = System.currentTimeMillis();
        System.out.println("AudiCarTimeProxy move end ");
        System.out.println("callback move 耗时为:"+(end-start)+"ms");
    }
}

public class AudiCarLogProxy implements Movable {
    
    private Movable thing;
    
    public AudiCarLogProxy(Movable thing) {
        this.thing = thing;
    }

    @Override
    public void move() {
        System.out.println("AudiCarLogProxy move start");
        thing.move();
        System.out.println("AudiCarLogProxy move end");
    }

}
View Code

步骤4:调用者测试

public class StaticProxyDemo01 {
    public static void main(String[] args) {
        new AudiCarTimeProxy(new AudiCarLogProxy(new AudiCar())).move();
        System.out.println("--------------------------------------------------");
        new AudiCarLogProxy(new AudiCarTimeProxy(new AudiCar())).move();
    }
}

步骤5:运行程序,观察结果

AudiCarTimeProxy move start 
AudiCarLogProxy move start
AudiCar is moving cacaca.....................
AudiCarLogProxy move end
AudiCarTimeProxy move end 
callback move 耗时为:402ms
--------------------------------------------------
AudiCarLogProxy move start
AudiCarTimeProxy move start 
AudiCar is moving cacaca.....................
AudiCarTimeProxy move end 
callback move 耗时为:661ms
AudiCarLogProxy move end

五、动态代理UML类图

 六、动态代理实现

  步骤1:创建接口

public interface Movable {
    void move();  
}

步骤2:创建实现接口的实体类

public class AudiCar implements Movable{
    @Override
    public void move() {
        System.out.println("AudiCar is moving cacaca....................................");
    }
}

步骤3:创建处理类Handler对象

public class ProxyHandler implements InvocationHandler{
    
    private Movable thing;
    
    public ProxyHandler(Movable thing) {
        this.thing = thing;
    }

    @Override
    public Object invoke(Object proxy, Method method, Object[] args) throws Throwable {
        method.invoke(thing, args);
        return null;
    }
}

步骤4:调用者测试

import java.lang.reflect.Proxy;
import gof.com.yew.proxy.staticproxy.AudiCar;
import gof.com.yew.proxy.staticproxy.Movable;
public class ProxyDemo01 {    
    public static void main(String[] args) {
        Movable audi = new AudiCar();
        System.getProperties().put("sun.misc.ProxyGenerator.saveGeneratedFiles", "true");//保存jdk动态代理生成的动态代理类class文件
        ProxyHandler handler = new ProxyHandler(audi);
        Movable proxy = (Movable)Proxy.newProxyInstance(ClassLoader.getSystemClassLoader(), new Class[] {Movable.class}, handler);
        proxy.move();
    }
}

步骤5:运行程序,观察结果

 

、动态代理生成的类分析

package com.sun.proxy;
import gof.com.yew.proxy.staticproxy.Movable;
import java.lang.reflect.InvocationHandler;
import java.lang.reflect.Method;
import java.lang.reflect.Proxy;
import java.lang.reflect.UndeclaredThrowableException;

public final class $Proxy0 extends Proxy implements Movable   //动态代理类继承了Proxy并且实现了Movable接口
{
  private static Method m1;
  private static Method m3;
  private static Method m2;
  private static Method m0;
  
  public $Proxy0(InvocationHandler paramInvocationHandler)
    throws 
  {
    super(paramInvocationHandler);
  }
  
  public final boolean equals(Object paramObject)
    throws 
  {
    try
    {
      return ((Boolean)this.h.invoke(this, m1, new Object[] { paramObject })).booleanValue();
    }
    catch (Error|RuntimeException localError)
    {
      throw localError;
    }
    catch (Throwable localThrowable)
    {
      throw new UndeclaredThrowableException(localThrowable);
    }
  }
  
  public final void move()//重写movable接口
    throws 
  {
    try
    {
      this.h.invoke(this, m3, null);
      return;
    }
    catch (Error|RuntimeException localError)
    {
      throw localError;
    }
    catch (Throwable localThrowable)
    {
      throw new UndeclaredThrowableException(localThrowable);
    }
  }
  
  public final String toString()
    throws 
  {
    try
    {
      return (String)this.h.invoke(this, m2, null);
    }
    catch (Error|RuntimeException localError)
    {
      throw localError;
    }
    catch (Throwable localThrowable)
    {
      throw new UndeclaredThrowableException(localThrowable);
    }
  }
  
  public final int hashCode()
    throws 
  {
    try
    {
      return ((Integer)this.h.invoke(this, m0, null)).intValue();
    }
    catch (Error|RuntimeException localError)
    {
      throw localError;
    }
    catch (Throwable localThrowable)
    {
      throw new UndeclaredThrowableException(localThrowable);
    }
  }
  
  static
  {
    try
    {
      m1 = Class.forName("java.lang.Object").getMethod("equals", new Class[] { Class.forName("java.lang.Object") });
      m3 = Class.forName("gof.com.yew.proxy.staticproxy.Movable").getMethod("move", new Class[0]);
      m2 = Class.forName("java.lang.Object").getMethod("toString", 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());
    }
  }
}

 

 

posted on 2020-03-29 20:10  VincentYew  阅读(212)  评论(0)    收藏  举报

导航