源码网商城,靠谱的源码在线交易网站 我的订单 购物车 帮助

源码网商城

java代理模式与动态代理模式详解

  • 时间:2021-11-06 11:46 编辑: 来源: 阅读:
  • 扫一扫,手机访问
摘要:java代理模式与动态代理模式详解
1、代理模式 所谓代理,就是一个人或者一个机构代表另一个人或者另一个机构采取行动。在一些情况下,一个客户不想或者不能够直接引用一个对象,而代理对象可以在客户端和目标对象之前起到中介的作用。 代理模式给某一个对象提供一个代理对象,并由代理对象控制对原对象的引用。 生活中的例子:过年加班比较忙,没空去买火车票,这时可以打个电话到附近的票务中心,叫他们帮你买张回家的火车票,当然这会附加额外的劳务费。但要清楚票务中心自己并不卖票,只有火车站才真正卖票,票务中心卖给你的票其实是通过火车站实现的。这点很重要! 上面这个例子,你就是“客户”,票务中心就是“代理角色”,火车站是“真实角色”,卖票称为“抽象角色”! 代理模式JAVA代码示例: 抽象角色:抽象类或接口
[u]复制代码[/u] 代码如下:
interface Business  {      void doAction();  }  
真实角色:真正实现了业务逻辑接口 代理角色:自己并未实现业务逻辑接口,而是调用真实角色来实现
[u]复制代码[/u] 代码如下:
class BusinessImplProxy implements Business  {      private BusinessImpl bi;      public void doAction()      {          if (bi==null)          {              bi = new BusinessImpl();          }          doBefore();          bi.doAction();          doAfter();      }      public void doBefore()      {          System.out.println("前置处理!");      }      public void doAfter()      {          System.out.println("后置处理!");      }  }  //测试类  class Test  {      public static void main(String[] args)      {          //引用变量定义为抽象角色类型          Business bi = new BusinessImplProxy();          bi.doAction();      }  }
[u]复制代码[/u] 代码如下:
<span></span>
所以,借助于JVM的支持,可以在运行时动态生成代理类(“代理角色”),我们就可以解决上述代理模式中代码膨胀的问题,使用了动态代理后,“代理角色”将不用手动生成,而由JVM在运行时,通过指定类加载器、接口数组、调用处理程序这3个参数来动态生成。 动态代理模式JAVA代码示例:
[u]复制代码[/u] 代码如下:
import java.lang.reflect.InvocationHandler;  import java.lang.reflect.Proxy;  import java.lang.reflect.Method;  //抽象角色:java动态代理的实现目前只支持接口,不支持抽象类  interface BusinessFoo  {      void foo();  }  interface BusinessBar {     String bar(String message); } //真实角色:真正实现业务逻辑方法 class BusinessFooImpl implements BusinessFoo {     public void foo()     {         System.out.println("BusinessFooImpl.foo()");     } } class BusinessBarImpl implements BusinessBar {     public String bar(String message)     {         System.out.println("BusinessBarImpl.bar()");         return message;     } } //动态角色:动态生成代理类 class BusinessImplProxy implements InvocationHandler {     private Object obj;     BusinessImplProxy() {     }     BusinessImplProxy(Object obj) {         this.obj = obj;     }     public Object invoke(Object proxy,Method method,Object[] args) throws Throwable     {         Object result = null;         doBefore();         result = method.invoke(obj,args);         doAfter();         return result;     }     public void doBefore(){         System.out.println("do something before Business Logic");     }     public void doAfter(){         System.out.println("do something after Business Logic");     }     public static Object factory(Object obj)     {         Class cls = obj.getClass();         return Proxy.newProxyInstance(cls.getClassLoader(),cls.getInterfaces(),new BusinessImplProxy(obj));     } } //测试类 public class DynamicProxy {        public static void main(String[] args) throws Throwable     {         BusinessFooImpl bfoo = new BusinessFooImpl();         BusinessFoo bf = (BusinessFoo)BusinessImplProxy.factory(bfoo);         bf.foo();         System.out.println();         BusinessBarImpl bbar = new BusinessBarImpl();         BusinessBar bb = (BusinessBar)BusinessImplProxy.factory(bbar);         String message = bb.bar("Hello,World");         System.out.println(message);     } }
程序流程说明: new BusinessFooImpl();创建一个“真实角色”,传递给工厂方法BusinessImplProxy.factory(),进而初始化“调用处理器”——即实现InvocationHandler的类。并返回一个动态创建的代理类实例,由于“代理角色”也必然实现了“抽象角色”提供的业务逻辑方法,故可向下转型为BusinessBar,并赋值给指向BusinessBar类型的引用bb。 newProxyInstance(ClassLoader loader, Class<?>[] interfaces, InvocationHandler h)方法由程序员来指定参数动态返回需要的代理类,而invoke(Object proxy, Method method, Object[] args) 方法则是由JVM在运行时动态调用的。当执行“bb.bar("Hello,World");”方法时,JVM动态指派“调用处理器”,向外层invoke传递参数,并调用method.invoke(obj,args)真正执行! BusinessImplProxy.Factory静态方法用来动态生成代理类(“代理角色”),在运行时根据不同的业务逻辑接口BusinessFoo和BusinessBar,在运行时分别动态生成了代理角色。“抽象角色”、“代理角色”以及调用处理器(实现InvocationHandler接口的类)这三者都可以改变,所以说JAVA的动态代理十分强大。
  • 全部评论(0)
联系客服
客服电话:
400-000-3129
微信版

扫一扫进微信版
返回顶部