详解JAVA设计模式之代理模式

什么是设计模式(Design Pattern)?

  设计模式是一套被反复使用,多数人知晓的,经过分类编目的,代码设计经验的总结。

代理模式的定义?

  代理模式就是为其他对象提供一种代理,以控制对这个对象的访问。

  代理对象起到中介作用,可去掉功能服务或增加额外的服务。

代理对象和目标对象的关系?

  代理对象:增强后的对象

  目标对象:被增强的对象

  他们不是绝对的,会根据情况发生变化。

代理模式的两种实现方式?

  1.静态代理:代理和被代理对象在代理之前是确定的,它们都实现相同的接口或者继承相同的抽象类。

  2.动态代理:JDK通过接口反射得到字节码,然后把字节码转换成class(通过native方法)

静态代理实现的两种方式?

  使用继承方式实现和使用聚合方式实现。

  继承:代理对象继承目标对象,重写需要增强的方法。缺点:代理类过多,产生类爆炸。

  聚合:目标对象和代理对象实现同一个接口,代理对象当中要包含目标对象。

动态代理的实现方式?

  Java动态代理类位于java.lang.reflect包下,一般主要涉及到以下两个类:

    1.Interface InvocationHandler : 该接口中仅定义了一个方法,public Object invoke(Object obj,Method method,Object[] args),在实际使用时,第一个参数obj一般是指代理类,method是被代理的方法,args是该方法的参数数组,这个抽象方法在代理类中动态实现。

    2.Proxy 该类即为动态代理类,static Object newProxyInstance(ClassLoader loader,Class[] interfaces,InvocationHandler h):返回代理类的一个实例,返回后的代理类可以当做被代理类使用(可使用被代理类在接口中声明过的方法)

    所谓的动态代理是这样一种class:它是在运行时生成的class,该class需要实现一组interface,使用动态代理类时,必须实现InvocationHandler接口。

JDK动态代理和CGLIB动态代理的区别?

  1.JDK动态代理只能代理实现了接口的类,没有实现接口的类不能实现JDK的动态代理。

  2.CGLIB动态代理针对类来实现代理的,对指定目标类产生一个子类,通过方法拦截技术拦截所有的父类方法的调用。

动态代理实现的思路:

  1.声明一段源码(动态产生代理)

  2.编译源码(JDK Compiler API ),产生新的类(代理类)

  3.将这个类load到内存中,产生一个新的对象(代理对象)

  4.return 代理对象。

使用静态代理的例子:

  1.首先创建业务逻辑接口

/**
 * 接口
 * @author Administrator
 *
 */
public interface Moveable {
  /**
   *
   * 接口中的方法
   * @Description: TODO
   * @returnType: void
   */
  void move();
}

  2.创建实现类,实现接口中的方法

/**
 * 实现类
 * @author Administrator
 *
 */
public class Car implements Moveable {

  @Override
  public void move() {
    //实现开车
    try {
      Thread.sleep(new Random().nextInt(1000));
      System.out.println("汽车行驶中...");
    } catch (InterruptedException e) {
      e.printStackTrace();
    }
  }

}

  3.使用继承方式实现对实现类的代理

/**
 * 使用继承方式实现代理
 * @author Administrator
 *
 */
public class Car2 extends Car {

  /* (non-Javadoc)
   * @see com.wk.design.proxy.Car#move()
   * 直接调用父类的move方法,这样就形成了一个Car2对Car的代理
   */
  @Override
  public void move() {
    long startTime = System.currentTimeMillis();
    System.out.println("汽车开始行驶...");
    //使用继承的方式调用父类的move()方法
    super.move();
    long endTime = System.currentTimeMillis();
    System.out.println("汽车行驶结束... 汽车行驶时间:"+(endTime-startTime)+"毫秒。");
  }

}

  4.创建测试类

/**
 * 测试类
 * @author Administrator
 *
 */
public class Test {

  public static void main(String[] args) {
//    Car car = new Car();
//    car.move();

    //使用继承方式实现代理
    Moveable car2 = new Car2();
    car2.move();

    //使用聚合方式实现代理
//    Car car = new Car();
//    Moveable car3 = new Car3(car);
//    car3.move();

  }
}

  5.使用聚合方式实现对实现类的代理

    日志代理类

/**
 *
 * 日志代理类
 * @author Administrator
 *
 */
public class CarLogProxy implements Moveable {

  /**
   * 使用接口声明代理类
   */
  private Moveable m;
  /**
   * 通过构造方法的参数传入代理类
   * @param m
   */
  public CarLogProxy(Moveable m) {
    super();
    this.m = m;
  }

  @Override
  public void move() {
    System.out.println("日志开始");
    //调用代理类的方法
    m.move();
    System.out.println("日志结束");

  }

}

    时间代理类

/**
 * 时间代理类
 * @author Administrator
 *
 */
public class CarTimeProxy implements Moveable {

  /**
   * 使用接口声明代理类
   */
  private Moveable m;
  /**
   * 通过构造方法的参数传入代理类
   * @param m
   */
  public CarTimeProxy(Moveable m) {
    super();
    this.m = m;
  }

  @Override
  public void move() {
    long startTime = System.currentTimeMillis();
    System.out.println("汽车开始行驶...");
    //调用代理类的方法
    m.move();
    long endTime = System.currentTimeMillis();
    System.out.println("汽车行驶结束... 汽车行驶时间:"+(endTime-startTime)+"毫秒。");
  }

}

  6.创建聚合方式测试类

/**
 * 聚合代理测试类
 * @author Administrator
 *
 */
public class TestJuHeProxy {
  public static void main(String[] args) {
    Car car = new Car();
    //先记录日志,再记录时间
//    CarTimeProxy ctp = new CarTimeProxy(car);
//    CarLogProxy clp = new CarLogProxy(ctp);
//    clp.move();

    //先记录时间,再记录日志
    CarLogProxy clp = new CarLogProxy(car);
    CarTimeProxy ctp = new CarTimeProxy(clp);
    ctp.move();
  }

}

使用JDK动态代理实现的例子:

  1.创建一个实现接口InvocationHandler的类,它必须实现invoke()方法。

  2.创建被代理类及接口

  3.调用Proxy的静态方法,创建一个代理类

  4.通过代理调用方法

/**
 * 使用jdk的动态代理
 * @author Administrator
 *
 */
public class TimeHandler implements InvocationHandler {

  /**
   * 被代理对象
   */
  private Object target;

  public TimeHandler(Object target) {
    super();
    this.target = target;
  }

  /**
   * 参数:
   * proxy : 被代理对象
   * method : 被代理对象的方法
   * args : 方法的参数
   * 返回值:
   * Object 方法的返回值
   */
  @Override
  public Object invoke(Object proxy, Method method, Object[] args) throws Throwable {
    //在执行被代理对象的方法之前执行自己的逻辑
    long startTime = System.currentTimeMillis();
    System.out.println("汽车开始行驶...");
    //执行被代理对象的方法
    method.invoke(target);
    //在执行被代理对象的方法之后执行自己的逻辑
    long endTime = System.currentTimeMillis();
    System.out.println("汽车行驶结束... 汽车行驶时间:"+(endTime-startTime)+"毫秒。");
    return null;
  }

}
 /**
  * JDK动态代理测试类
  * @author Administrator
  *
  */
 public class JdkProxyTest {

   public static void main(String[] args) {
     Car car = new Car();
     InvocationHandler h = new TimeHandler(car);
     Class<?> cls = car.getClass();
     /**
     * 参数:
     *   loader : 类加载器
     * interfaces : 实现接口
     * h InvocationHandler
     */
     Moveable m= (Moveable)Proxy.newProxyInstance(cls.getClassLoader(), cls.getInterfaces(), h);
     //执行被代理类的方法
     m.move();
   }

 }

使用CGLIB动态代理实现的例子:

  1.创建代理类,实现MethodInterceptor接口

  2.使用Enhancer类创建代理方法

  3.创建被代理类,并编写代理方法

  4.通过代理调用方法

/**
 * 使用cglib动态代理
 * @author Administrator
 *
 */
public class Train {
  public void move(){
    System.out.println("火车行驶中。。。");
  }
}
public class CglibProxy implements MethodInterceptor {

  private Enhancer enhancer = new Enhancer();
  //创建代理类方法
  public Object getProxy(Class clazz){
    //设置创建子类的类
    enhancer.setSuperclass(clazz);
    //回调函数
    enhancer.setCallback(this);
    //创建并返回子类的实例
    return enhancer.create();
  }
  /**
   * 作用:拦截所有目标类方法的调用
   * obj : 目标类的实例
   * m : 目标方法的反射对象
   * args : 方法的参数
   * proxy : 代理类的实例
   */
  @Override
  public Object intercept(Object obj, Method m, Object[] args, MethodProxy proxy) throws Throwable {
    //在调用方法时实现自己的业务逻辑
    System.out.println("日志开始...");
    //代理类调用父类的方法
    proxy.invokeSuper(obj, args);
    //调用方法之后实现自己的业务逻辑
    System.out.println("日志结束...");
    return null;
  }
}
 /**
  * 使用cglib动态代理的测试类
  * @author Administrator
  *
  */
 public class CglibProxyTest {

   public static void main(String[] args) {
     CglibProxy proxy = new CglibProxy();
     //传入要代理的类
     Train t = (Train)proxy.getProxy(Train.class);
     //执行方法
     t.move();
   }

 }

以上就是详解JAVA设计模式之代理模式的详细内容,更多关于JAVA 代理模式的资料请关注我们其它相关文章!

(0)

相关推荐

  • java设计模式笔记之代理模式

    代理(Proxy)模式: 代理模式是对象的结构模式.代理模式给某一个对象提供一个代理对象,并由代理对象控制对原对象的引用. 核心作用: 通过代理,控制对对象的访问. 可以详细控制访问某个(某类)对象的方法,在调用这个方法之前做前置处理,在调用这个方法之后做后置处理.即AOP的微观实现. AOP(Aspect Oriented Programming面向切面编程)的核心实现机制. 生活中的场景: 所谓代理,就是一个人或者机构代表另一个人或者机构采取行动.在一些情况下,一个客户不想或者不能够直接引用

  • java设计模式-代理模式(实例讲解)

    代理模式是java最常见的设计模式之一.spring的aop就是使用了代理模式. 一般而言,代理模式分为静态代理和动态代理两种. 作为结构类的设计模式,作用在于不修改类内部代码的情况下,对类进行拓展,是对继承机制的一种补充. eg :下面就用户登录这个例子实现一下代理模式. 基本需求是:实现用户的登录和修改昵称功能. 上代码,先是IUser接口和user实现类 public interface IUser { //登录 void login(String userId,String passwo

  • Java设计模式之代理模式与装饰模式实例详解

    本文实例讲述了Java设计模式之代理模式与装饰模式.分享给大家供大家参考,具体如下: 之所以把这两种模式放在一起说,是因为我发现这了两种模式几乎一模一样! 从网上也搜了一些资料,发现两者还是有一些区别的.我们在学习的同时也把这种困惑搞清楚. 定义: 代理模式,为其他对象提供一种代理以控制对这个对象的访问. 装饰模式,动态地给一个对象添加一些额外的职责. 代理模式,很好理解,就是把一个对象再次封装,以后就对封装的对象访问就可以了. 因为代理对象已经取代了被代理对象. 装饰模式,给一个对象增加功能,

  • Java设计模式之静态代理模式实例分析

    本文实例讲述了Java设计模式之静态代理模式.分享给大家供大家参考,具体如下: 代理模式,可以通过代理可以在原来的基础上附加一些其他的操作.静态代理模式相对比较简单无需再程序运行时动态的进行代理. 静态代理模式的角色: ① 抽象角色:真实对象和代理对象的共同接口.其中声明真实对象和代理对象需要做的事. ② 真实角色:实现抽象角色,定义真实角色所要实现的业务逻辑,供代理角色调用. ③ 代理角色:实现抽象角色,是真实角色的代理,通过真实角色的业务逻辑方法来实现抽象方法,并可以附加自己的操作. 下面提

  • Java设计模式之动态代理模式实例分析

    本文实例讲述了Java设计模式之动态代理模式.分享给大家供大家参考,具体如下: 前面介绍了静态代理模式,动态代理比静态代理模式更加强大.它能在程序运行时动态的生成代理对象.所谓动态代理类是在运行时生成的class,在生成它时,你必须提供一组interface给它,则动态代理类就宣称它实现了这些interface.当然,动态代理类就充当一个代理,你不要企图它会帮你干实质性的工作,在生成它的实例时你必须提供一个handler,由它接管实际的工作. 动态代理的角色和静态代理的角色一样: ① 抽象角色:

  • java设计模式学习之代理模式

    代理模式(Proxy):为其他对象提供一种代理以控制对这个对象的访问. 代理模式结构图 模拟需求:3班小张喜欢1班小红,但是不认识小红,委托1班小明送给小红礼物. 1:创建一个小张和小明都能实现的接口. package ProxyModel; /** * 总的接口 * @author 我不是张英俊 * */ interface ISendGift { void GiveDolls(); void GiveFlowers(); void GiveChocolate(); } 2:实现小张送礼物.

  • 23种设计模式(7) java代理模式

    23种设计模式第七篇:java代理模式 定义: 为其他对象提供一种代理以控制对这个对象的访问.在某些情况下,一个对象不适合或者不能直接引用另一个对象,而代理对象可以在客户端和目标对象之间起到中介的作用 角色: 1.抽象角色:声明真实对象和代理对象的共同接口. 2.代理角色:代理对象角色内部含有对真实对象的引用,从而可以操作真实对象,同时代理对象提供与真实对象相同的接口以便在任何时刻都能代替真实对象.同时,代理对象可以在执行真实对象操作时,附加其他的操作,相当于对真实对象进行封装. 3.真实角色:

  • Java设计模式之代理模式_动力节点Java学院整理

    引言 Java 动态代理机制的出现,使得 Java 开发人员不用手工编写代理类,只要简单地指定一组接口及委托类对象,便能动态地获得代理类.代理类会负责将所有的方法调用分派到委托对象上反射执行,在分派执行的过程中,开发人员还可以按需调整委托类对象及其功能,这是一套非常灵活有弹性的代理框架.通过阅读本文,读者将会对 Java 动态代理机制有更加深入的理解.本文首先从 Java 动态代理的运行机制和特点出发,对其代码进行了分析,推演了动态生成类的内部实现. 代理:设计模式 代理是一种常用的设计模式,其

  • Java设计模式之代理模式原理及实现代码分享

    简介 Java编程的目标是实现现实不能完成的,优化现实能够完成的,是一种虚拟技术.生活中的方方面面都可以虚拟到代码中.代理模式所讲的就是现实生活中的这么一个概念:中介. 代理模式的定义:给某一个对象提供一个代理,并由代理对象控制对原对象的引用. 代理模式包含如下角色: ISubject:抽象主题角色,是一个接口.该接口是对象和它的代理共用的接口. RealSubject:真实主题角色,是实现抽象主题接口的类. Proxy:代理角色,内部含有对真实对象RealSubject的引用,从而可以操作真实

  • 详解设计模式中的proxy代理模式及在Java程序中的实现

    一.代理模式定义 给某个对象提供一个代理对象,并由代理对象控制对于原对象的访问,即客户不直接操控原对象,而是通过代理对象间接地操控原对象. 著名的代理模式的例子就是引用计数(reference counting): 当需要一个复杂对象的多份副本时, 代理模式可以结合享元模式以减少存储器的用量.典型做法是创建一个复杂对象以及多个代理者, 每个代理者会引用到原本的对象.而作用在代理者的运算会转送到原本对象.一旦所有的代理者都不存在时, 复杂对象会被移除. 要理解代理模式很简单,其实生活当中就存在代理

  • java设计模式之代理模式(Porxy)详解

    一.什么是代理模式(Porxy) 概念:代理模式就是为其他对象提供一种代理以控制对这个对象的访问. 现实生活中也有很多行为吻合代理模式.比如店外卖,客户在APP上下单后,店长会接单.这个时候店长可以选择自己去送这份外卖,也可以委托送餐员代理店长去送这份外卖.当然店长是可以自己送,但店长送了外卖店就没人看着了,而让送餐员代理送外卖就不会这样了.这里很显然店长是对象本尊(Subject),送餐员是代理对象(Proxy ),代理对象中有店长给的订单信息,比如送到哪里,几点之前要送到,这就说明代理对象中

随机推荐