GOF23设计模式之动态代理模式实现之经典


/**
 * 抽象就角色,定义代理角色和真实角色的公共对外方法
 * 时间:2015年4月4日18:45:00
 * 在这个例子中,抽象角色起着规范代理角色和真实角色的作用。
 * 其中具有方法,面谈,签合同收预付款,预订机票,唱歌,收尾款
 */
package com.bjsxt.cn.proxy.dynamicProxy;
public interface Star {
 void confer();
 void signContract();
 void bookTicket();
 void sing();
 void collectMoney();
}


/**
 * 相当于真实角色,实现抽象角色,定义真实角色所要实现的业务逻辑,供代理角色使用
 * 也就是这个类的对象(例如周杰伦),他要实现他的sing方法,这是他的药关注的业务逻辑。这个实现了的
 * sing方法是为了供代理角色使用的
 *
 * 只需要关注真正的业务逻辑,其他方法是不用关注的
 */
package com.bjsxt.cn.proxy.dynamicProxy;
public class RealStar implements Star {
 /**
  * 面谈
  */
 @Override
 public void confer() {
  System.out.println("RealStar.confer()");
 }
 @Override
 public void signContract() {
  System.out.println("RealStar.signContract()");
  
 }
 @Override
 public void bookTicket() {
  System.out.println("RealStar.bookTicket()");
 }
 @Override
 public void sing() {
  System.out.println("RealStar(真实角色:周杰伦).sing()");
  
 }
 @Override
 public void collectMoney() {
  System.out.print("RealStar.collectMoney()");
  
 }
 
}

/**
 * 处理器接口InvocationHandler,可以通过invoke实现对真实角色的访问
 * 每次通过过Proxy生成的代理类对象时都要指定对应的处理器对象
 *
 */
package com.bjsxt.cn.proxy.dynamicProxy;
import java.lang.reflect.InvocationHandler;
import java.lang.reflect.Method;
/**
 * InvocationHandler接口是代理实例的调用程序实现的接口
 * 每个代理实例都具有一个关联的调用处理程序。对代理实例调用方法时,将对方法调用进行编码
 * 并将其指派到它的调用处理程序的invoke方法。
 * @author [email protected]
 *
 */
public class StarHandler implements InvocationHandler {
 Star realStar = null;
 
 
 public StarHandler(Star realStar) {
  super();
  this.realStar = realStar;
 }
 /**
  * 在代理实例上处理方法调用并返回结果,在于方法关联的代理实例上调用方法,将在调用
  * 处理程序上调用此方法
  * @param method
  *   对应用于在代理实例上调用的接口方法的Method实例。Method对象的生命类将是在其中声明方法
  *   ,该接口可以是代理类赖以继承方法的代理接口的超接口。
  *   
  *  @param args 包含传入代理实例上方法调用的参数值的对象数组。如果接口方法不使用参数,则为null
  *    注意:基本类型的参数被包装在适当的基本包装器类(java.lang.Integer或者java.lang.Boolean)的实例中
  *
  * @param proxy 在其上调用方法的代理实例
  *
  * @return
  *   从代理实例的方法调用返回的值。如果接口方法的声明返回类型是基本类型,
  *   则此方法返回的值一定是相应基本包装对象类的实例;
  *   否则,它一定是可分配到声明返回类型的类型。
  *    如果此方法返回的值为 null 并且接口方法的返回类型是基本类型,
  *   则代理实例上的方法调用将抛出 NullPointerException。
  *   否则,如果此方法返回的值与上述接口方法的声明返回类型不兼容,
  *   则代理实例上的方法调用将抛出 ClassCastException
  */
 @Override
 public Object invoke(Object proxy, Method method, Object[] args)
   throws Throwable {
  Object object =null;
  
  
  if (method.getName().equals("sing")) {
   System.out.println("面谈,签合约,收预付款,预定机票");
   System.out.println("在真正的方法调用前");
   object = method.invoke(realStar, args);
   System.out.println("在真正的方法调用后");
   System.out.println("收尾款");
   
  }
 
  
  return object;
 }
}


/**
 * 测试动态代理类
 * 时间:2015年4月4日20:01:43
 *
 */
package com.bjsxt.cn.proxy.dynamicProxy;
/**
 * Proxy类提供用于创建动态代理类和实例的静态方法,它还是由这些方法创建的所有动态代理类的超类
 *
 * 动态代理类是一个实现在创建类时在运行时指定的接口列标的类,该类具有以下行为:代理接口
 * 是指代理类实现的一个借口。代理实例是代理类的一个实例。每个代理类的代理实例上的方法调用将
 * 被指派到实例的调用处理程序的Invoke方法。并床底代理实例,识别调用方法的java.lang.reflect.Method对象以及包含的Object类型的
 * 数组。调用处理程序以适当的方式处理编码的方法调用。并且它返回的结果将作为代理实例上方法调用的结果返回。
 *
 *
 * 一般创建某一接口的Foo的代理:
 *  InvocationHandler handler = new MyInvocationHandler(...);//获得一个处理器
     Class proxyClass = Proxy.getProxyClass(
         Foo.class.getClassLoader(), new Class[] { Foo.class });
     Foo f = (Foo) proxyClass.
         getConstructor(new Class[] { InvocationHandler.class }).
         newInstance(new Object[] { handler });
        
  或者使用以下更简单的方法:(本例也使用的是下面的方法)
   
   
   Foo f = (Foo) Proxy.newProxyInstance(Foo.class.getClassLoader(),
                                          new Class[] { Foo.class },
                                          handler);
 */
import java.lang.reflect.Proxy;
public class Client {
 public static void main(String[] args) {
  Star realStar = new RealStar();
  StarHandler handler = new StarHandler(realStar);
  
  /**
   * 换言之,该代理类的实例proxy,实现了指定的接口列表中的类(我们在静态代理中也同样的实现了Star一样
   * ,就是因为实现了Star接口,所以我们可以声明为Star类型,这大概也是一种多态行为的使用吧。切切)
   *
   * 在这行代码中,Star.class表示的是代理接口(代理类实现的一个接口)。代理实例指的是proxy,它实现了Star接口
   */
  Star proxy = (Star) Proxy.newProxyInstance(ClassLoader.getSystemClassLoader(), new Class[]{Star.class} , handler);
 // proxy.bookTicket();
  /**
   * 在这行代码中,我们可以粗略的获得三种信息,proxy是代理实例,方法名是sing,该方法没有参数,
   * 全部传递给了与该代理实例所关联的调用处理程序。
   */
  proxy.sing();
 }
}
/*
 *
 *
面谈,签合约,收预付款,预定机票
在真正的方法调用前
RealStar(真实角色:周杰伦).sing()
在真正的方法调用后
收尾款
 * */


				
时间: 2024-07-31 14:31:35

GOF23设计模式之动态代理模式实现之经典的相关文章

GOF23设计模式之静态代理模式实现之经典

 /**  * 抽象就角色,定义代理角色和真实角色的公共对外方法  * 时间:2015年4月4日18:45:00  * 在这个例子中,抽象角色起着规范代理角色和真实角色的作用.  * 其中具有方法,面谈,签合同收预付款,预订机票,唱歌,收尾款  */ package com.bjsxt.cn.proxy.staticProxy; public interface Star {  void confer();  void signContract();  void bookTicket();

设计模式之动态代理模式

设计模式之动态代理模式 代理模式: Provide a surrogate or placeholder for another object to controlaccess to it(为其他对象提供一种代理以控制对这个对象的访问).使用代理模式创建代理对象,让代理对象控制目标对象的访问(目标对象可以是远程的对象.创建开销 大的对象或需要安全控制的对象),并且可以在不改变目标对象的情况下添加一些额外的功能. 代理模式相关内容详见本人之前文章:http://www.cnblogs.com/zh

Java设计模式—Proxy动态代理模式

代理:设计模式 代理是一种常用的设计模式,其目的就是为其他对象提供一个代理以控制对某个对象的访问.代理类负责为委托类预处理消息,过滤消息并转发消息,以及进行消息被委托类执行后的后续处理. 图 1. 代理模式 为了保持行为的一致性,代理类和委托类通常会实现相同的接口,所以在访问者看来两者没有丝毫的区别.通过代理类这中间一层,能有效控制对委托类对象的直接访问,也可以很好地隐藏和保护委托类对象,同时也为实施不同控制策略预留了空间,从而在设计上获得了更大的灵活性.Java 动态代理机制以巧妙的方式近乎完

设计模式之动态代理模式实战

动态代理在我们工作当中应用相当广泛,如Srping AOP就是动态代理的在开源框架的比较出名的应用.动态代理有两种试:一是通过JDK自带的API实现动态代理,二是通过别的字节码框架实现,如cglib.需要注意的是JDK只能针对接口实现动态代理,不能代理普通类,使用具有局限性.而cglib可以代理接口及所有的普通类. 用户接口 public interface UserInterface { boolean saveUser(User user); } 用户接口实现 public class Us

23种设计模式----------代理模式(三) 之 动态代理模式

(上一篇)种设计模式----------代理模式(二) 当然代理模式中,用的最广泛的,用的最多的是  动态代理模式. 动态代理:就是实现阶段不用关系代理是哪个,而在运行阶段指定具体哪个代理. 抽象接口的类图如下: --图来自设计模式之禅 所以动态代理模式要有一个InvocationHandler接口 和 GamePlayerIH实现类.其中 InvocationHandler是JD提供的动态代理接口,对被代理类的方法进行代理. 代码实现如下 抽象主题类或者接口: 1 package com.ye

Android开发中无处不在的设计模式——动态代理模式

继续更新设计模式系列,写这个模式的主要原因是最近看到了动态代理的代码. 先来回顾一下前5个模式: - Android开发中无处不在的设计模式--单例模式 - Android开发中无处不在的设计模式--Builder模式 - Android开发中无处不在的设计模式--观察者模式 - Android开发中无处不在的设计模式--原型模式 - Android开发中无处不在的设计模式--策略模式 动态代理模式在Java WEB中的应用简直是随处可见,尤其在Spring框架中大量的用到了动态代理:算是最重要

关于装饰模式和动态代理模式

装饰模式和动态代理模式乍一看差不多,都是动态的增加行为,其实有各自的区别. 一.首先我们看一下装饰设计模式,其基本思想如下: 1.编写一个类,实现与被装饰类相同的接口.目的使他们有相同的行为 2.定义一个实例变量,引用被装饰对象.目的和原来的老对象进行交接 3.定义构造方法,把被装饰对象注入进来. 4.对于不需要改写的方法,调用被装饰对象的. 5.对于要改写的方法,改写即可. 废话不多说,举一个例子,模拟实现一个数据库连接池,在这里,我想重写close方法,以实现调用close方法之后不是关闭连

深入解析Java设计模式之动态代理

深入解析Java设计模式之动态代理 代理是基本的设计模式之一,它是你为了提供额外的或不同的操作,而插入的用来代替"实际"对象的对象.这些操作通常涉及与"实际"对象的通信,因此代理通常充当着中间人的角色,下面是一个用来展示动态代理结构的简单示例: /** 普通(非动态)代理示例: */ interface Interface { void doSomething(); void somethingElse(String arg); } class RealObject

设计模式学习--------12.代理模式学习

场景: 福尔摩斯一直想送礼物给花生,但是羞于直接赠送,于是想到让房东太太去帮忙送礼物.编程如何实现呢? 定义: 为其他对象提供一种代理以控制对这个对象的访问. 角色: Proxy:代理对象.有下列功能: 实现与具体的目标对象一样的接口,这样就可以使用代理来代替具体的目标对象. 持有一个具体目标对象的引用,可以在需要时调用具体的目标对象. 可以控制对目标对象的访问,并可以负责创建和删除它. package com.kris.study; public class Proxy implements