华南俳烁实业有限公司

java

當(dāng)前位置:中華考試網(wǎng) >> java >> java教程 >> 文章內(nèi)容

使用Proxy模式及Java內(nèi)建的動(dòng)態(tài)代理機(jī)制

來(lái)源:中華考試網(wǎng)  [2020年12月3日]  【

  1.Proxy模式

  代理模式支持將某些操作從實(shí)際的對(duì)象中分離出來(lái),通過(guò)它的代理類提供處理。這樣便于修改和管理這些特定的操作。

  <>Subject.java

  package com.zj.proxy;

  public interface Subject {

  void operation1();

  void operation2(String arg);

  }

  現(xiàn)實(shí)類RealSubject.java

  package com.zj.proxy;

  public class RealSubject implements Subject {

  public void operation1() {

  System.out.println("Realer do operation1");

  填寫(xiě)下面表單即可預(yù)約申請(qǐng)免費(fèi)試聽(tīng)java課程!害怕學(xué)不會(huì)?助教陪讀,隨時(shí)解惑!擔(dān)心就業(yè)?一地學(xué)習(xí),可全國(guó)推薦就業(yè)!

java課程免費(fèi)學(xué)習(xí),高薪觸手可得

  • 地區(qū):
  • 姓名:
  • 手機(jī):

  }

  public void operation2(String arg) {

  System.out.println("Realer do operation2 with " + arg);

  }

  }

  代理類ProxySubject.java

  package com.zj.proxy;

  public class ProxySubject implements Subject {

  private Subject proxied;// 被代理對(duì)象

  public ProxySubject(Subject proxied) {

  this.proxied = proxied;

  }

  public void operation1() {

  System.out.println("Proxyer do operation1");

  proxied.operation1();

  }

  public void operation2(String arg) {

  System.out.println("Proxyer do operation2 with " + arg);

  proxied.operation2(arg);

  }

  }

  測(cè)試類SimpleProxyDemo.java

  package com.zj.proxy.client;

  import com.zj.proxy.Subject;

  import com.zj.proxy.RealSubject;

  import com.zj.proxy.ProxySubject;

  public class SimpleProxyDemo {

  public static void consumer(Subject subject) {

  subject.operation1();

  subject.operation2("ZJ");

  }

  public static void main(String[] args) {

  RealSubject real = new RealSubject();

  System.out.println("===Without Proxy===");

  consumer(real);

  System.out.println("===Use Proxy===");

  consumer(new ProxySubject(real));

  }

  }

  結(jié)果:

  ===Without Proxy===

  Realer do operation1

  Realer do operation2 with ZJ

  ===Use Proxy===

  Proxyer do operation1

  Realer do operation1

  Proxyer do operation2 with ZJ

  Realer do operation2 with ZJ

  2.使用Java的動(dòng)態(tài)代理機(jī)制

  設(shè)計(jì)一個(gè)類用于實(shí)現(xiàn)InvocationHandle接口,InvocationHandler 是代理實(shí)例的調(diào)用處理程序?qū)崿F(xiàn)的接口。

  每個(gè)代理實(shí)例都具有一個(gè)關(guān)聯(lián)的調(diào)用處理程序。對(duì)代理實(shí)例調(diào)用方法時(shí),將對(duì)方法調(diào)用進(jìn)行編碼并將其指派到它的調(diào)用處理程序的 invoke 方法。

  <>InvocationHandle.java

  package java.lang.reflect;

  public interface InvocationHandler {

  public Object invoke(Object proxy, Method method, Object[] args)

  throws Throwable;

  }

  對(duì)應(yīng)invoke參數(shù):

  [1]proxy - 在其上調(diào)用方法的代理實(shí)例;

  [2]method - 對(duì)應(yīng)于在代理實(shí)例上調(diào)用的接口方法的 Method 實(shí)例;

  [3]args - 包含傳入代理實(shí)例上方法調(diào)用的參數(shù)值的對(duì)象數(shù)組,如果接口方法不使用參數(shù),則為 null。

  現(xiàn)在設(shè)計(jì)一個(gè)類實(shí)現(xiàn)該接口,并提供代理實(shí)例。

  DynamicProxyHandler.java

  package com.zj.proxy.dynamic;

  import java.lang.reflect.InvocationHandler;

  import java.lang.reflect.Method;

  public class DynamicProxyHandler implements InvocationHandler {

  private Object proxied;

  public DynamicProxyHandler(Object proxied) {

  this.proxied = proxied;

  }

  public Object invoke(Object proxy, Method method, Object[] args)

  throws Throwable {

  System.out.println("**** proxy: ****\n" + proxy.getClass()

  + "\nmethod: " + method + "\nargs: " + args);

  if (args != null)

  for (Object arg : args)

  System.out.println(" " + arg);

  return method.invoke(proxied, args);

  }

  }

  這里的private Object proxied;即代理實(shí)例,也即上文代理模式中介紹的RealSubject對(duì)象。

  在invoke()方法中,我們會(huì)打印它的所有參數(shù),并調(diào)用當(dāng)前代理的方法。

  測(cè)試類DynamicProxyDemo.java

  package com.zj.proxy.client;

  import java.lang.reflect.Proxy;

  import com.zj.proxy.Subject;

  import com.zj.proxy.RealSubject;

  import com.zj.proxy.dynamic.DynamicProxyHandler;

  public class DynamicProxyDemo {

  public static void consumer(Subject subject) {

  subject.operation1();

  subject.operation2("ZJ");

  }

  public static void main(String[] args) {

  RealSubject real = new RealSubject();

  System.out.println("===Without Proxy===");

  consumer(real);

  System.out.println("===Use Proxy===");

  Subject proxy = (Subject) Proxy.newProxyInstance(Subject.class

  .getClassLoader(), new Class[] { Subject.class },

  new DynamicProxyHandler(real));

  consumer(proxy);

  }

  }

  這里通過(guò)Proxy的靜態(tài)方法newProxyInstance(ClassLoader loader, Class[] interfaces,InvocationHandler h)生成代理類,并傳遞與其關(guān)聯(lián)的調(diào)用處理程序new DynamicProxyHandler(real)。

  對(duì)于newProxyInstance()的參數(shù):

  [1]loader - 定義代理類的類加載器 ;

  [2]interfaces - 代理類要實(shí)現(xiàn)的接口列表 ;

  [3]h - 指派方法調(diào)用的調(diào)用處理程序 。

  測(cè)試結(jié)果:

  ===Without Proxy===

  Realer do operation1

  Realer do operation2 with ZJ

  ===Use Proxy===

  **** proxy: ****

  class $Proxy0

  method: public abstract void com.zj.proxy.Subject.operation1()

  args: null

  Realer do operation1

  **** proxy: ****

  class $Proxy0

  method: public abstract void com.zj.proxy.Subject.operation2(java.lang.String)

  args: [Ljava.lang.Object;@de6f34

  ZJ

  Realer do operation2 with ZJ

  從結(jié)果可以發(fā)現(xiàn),通過(guò)代理可以得到當(dāng)前被調(diào)用的方法,及其參數(shù)。代理過(guò)程可以基于此進(jìn)行邏輯處理,測(cè)試程序只是簡(jiǎn)單的打印這些相關(guān)信息。

  如果你現(xiàn)在想學(xué)習(xí)Java,贏取高薪工作機(jī)會(huì),非常簡(jiǎn)單,填寫(xiě)下面信息,學(xué)好Java技術(shù)高薪工作機(jī)會(huì)唾手可得。

責(zé)編:fushihao
  • 會(huì)計(jì)考試
  • 建筑工程
  • 職業(yè)資格
  • 醫(yī)藥考試
  • 外語(yǔ)考試
  • 學(xué)歷考試
百色市| 沂水县| 宁夏| 龙陵县| 礼泉县| 彭阳县| 永川市| 深圳市| 漳浦县| 乌审旗| 高雄市| 前郭尔| 武胜县| 怀集县| 山东| 西华县| 高雄市| 徐汇区| 阿勒泰市| 鹤壁市| 芦山县| 赞皇县| 拜泉县| 庆元县| 中阳县| 永兴县| 东方市| 遂平县| 舞阳县| 枞阳县| 方山县| 高淳县| 英吉沙县| 鹰潭市| 巢湖市| 延吉市| 苍山县| 武安市| 商河县| 于田县| 女性|