熱點推薦:
您现在的位置: 電腦知識網 >> 編程 >> Java編程 >> Java核心技術 >> 正文

JAVA 動態代理

2022-06-13   來源: Java核心技術 

  在目前的Java開發包中包含了對動態代理的支持但是其實現只支持對接口的的實現即只能對實現了接口的類進行動態代理對於沒有實現任何借口的類不能進行動態代理其實現主要通過是javalangreflectProxy類和javalangreflectInvocationHandler接口

  Proxy 類主要用來獲取動態代理對象即動態代理類主要包括

  Protected Proxy(InvocationHandler h)構造函數估計用於給內部的h賦值

  Static Class getProxyClass (ClassLoader loader Class[] interfaces)獲得一個代理類其中loader是類裝載器interfaces是真實類所擁有的全部接口的數組

  Static Object newProxyInstance(ClassLoader loader Class[] interfaces InvocationHandler h)返回代理類的一個實例返回後的代理類可以當作被代理類使用(可使用被代理類的在Subject接口中聲明過的方法)

  InvocationHandler 接口用來約束調用者實現

  該接口中僅定義了一個方法 Object: invoke(Object objMethod methodObject[] args)在實際使用時第一個參數obj一般指代理類method是被代理的方法args為該方法的參數數組這個抽象方法在代理類中動態實現

  所謂Dynamic Proxy是這樣一種class:它是在運行時生成的class在生成它時你必須提供一組interface給它然後該class就宣稱它實現了這些interface你當然可以把該class的實例當作這些interface中的任何一個來用 當然啦這個Dynamic Proxy其實就是一個Proxy它不會替你作實質性的工作在生成它的實例時你必須提供一個handler由它接管實際的工作這兩段摘自網絡

  我做了個小例子HelloWorld是業務接口HelloWorldImpl是業務接口的實現類HelloWorldHandler是動態代理類這個動態代理類與 HelloWorld 或者 HelloWorldImpl 或者 HelloKitty 沒有任何直接的聯系在調用這個代理類時傳過來哪個業務接口的實現對象他就生成哪個對象的代理類

  Java代碼

  package comwhyDynamicProxy;

  /**

  * 業務接口

  * @author why

  *

  */

  public interface HelloWorld {

  public void sayHello();

  public String sayHelloWithReturnValue();

  }

  package comwhyDynamicProxy;

  /**

  * 業務接口

  * @author why

  *

  */

  public interface HelloWorld {

  public void sayHello();

  public String sayHelloWithReturnValue();

  }

  Java代碼

  package comwhyDynamicProxy;

  /**

  * 業務接口實現類

  * @author why

  *

  */

  public class HelloWorldImpl implements HelloWorld {

  public void sayHello() {

  Systemoutprintln(執行了 sayHello());

  }

  public String sayHelloWithReturnValue() {

  String str = HelloWorld!;

  Systemoutprintln(執行了 sayHelloWithReturnValue());

  return str;

  }

  }

  package comwhyDynamicProxy;

  /**

  * 業務接口實現類

  * @author why

  *

  */

  public class HelloWorldImpl implements HelloWorld {

  public void sayHello() {

  Systemoutprintln(執行了 sayHello());

  }

  public String sayHelloWithReturnValue() {

  String str = HelloWorld!;

  Systemoutprintln(執行了 sayHelloWithReturnValue());

  return str;

  }

  }

  假如業務接口和實現類有很多我不能為每一個目標對象都設置一個代理於是寫了一個對每一個目標對象都使用的代理類這個類的名字可能跟上面那兩個家伙比較像但跟他們真的沒有什麼親戚關系如果有一個類是 HelloKitty 的話來了也同樣歡迎

  Java代碼

  package comwhyDynamicProxy;

  import javalangreflectInvocationHandler;

  import javalangreflectMethod;

  import javalangreflectProxy;

  /**

  * 動態代理類

  * @author why

  *

  */

  public class HelloWorldHandler implements InvocationHandler {

  //要代理的原始對象

  private Object objOriginal;

  /**

  * 構造函數 (test 使用)

  * @param obj 要代理的原始對象

  */

  public HelloWorldHandler(Object obj) {

  thisobjOriginal = obj ;

  }

  /**

  * 無參數構造函數 (test 使用)

  *

  */

  public HelloWorldHandler() {

  }

  /**

  *  返回此代理對象的實例 (test 使用)

  * @param obj 要代理的原始對象

  * @return

  */

  public Object newProxy(Object obj) {

  thisobjOriginal = obj ;

  return ProxynewProxyInstance(objOriginalgetClass()getClassLoader() objOriginalgetClass()getInterfaces() this);

  }

  public Object invoke(Object proxy Method method Object[] args) throws Throwable {

  Object result;

  //方法調用之前

  doBefore();

  //調用原始對象的方法

  result = methodinvoke(thisobjOriginal args);

  //方法調用之後

  doAfter();

  return result;

  }

  private void doBefore() {

  Systemoutprintln(before method invoke!);

  }

  private void doAfter() {

  Systemoutprintln(after method invoke!);

  }

  }

  package comwhyDynamicProxy;

  import javalangreflectInvocationHandler;

  import javalangreflectMethod;

  import javalangreflectProxy;

  /**

  * 動態代理類

  * @author why

  *

  */

  public class HelloWorldHandler implements InvocationHandler {

  //要代理的原始對象

  private Object objOriginal;

  /**

  * 構造函數 (test 使用)

  * @param obj 要代理的原始對象

  */

  public HelloWorldHandler(Object obj) {

  thisobjOriginal = obj ;

  }

  /**

  * 無參數構造函數 (test 使用)

  *

  */

  public HelloWorldHandler() {

  }

  /**

  *  返回此代理對象的實例 (test 使用)

  * @param obj 要代理的原始對象

  * @return

  */

  public Object newProxy(Object obj) {

  thisobjOriginal = obj ;

  return ProxynewProxyInstance(objOriginalgetClass()getClassLoader() objOriginalgetClass()getInterfaces() this);

  }

  public Object invoke(Object proxy Method method Object[] args) throws Throwable {

  Object result;

  //方法調用之前

  doBefore();

  //調用原始對象的方法

  result = methodinvoke(thisobjOriginal args);

  //方法調用之後

  doAfter();

  return result;

  }

  private void doBefore() {

  Systemoutprintln(before method invoke!);

  }

  private void doAfter() {

  Systemoutprintln(after method invoke!);

  }

  }

  我寫了兩種獲取動態代理對象實例的方法一種實在測試類中創建(test一種是通過代理類返回(test以下是測試代碼

  Java代碼

  package comwhyDynamicProxy;

  import javalangreflectInvocationHandler;

  import javalangreflectProxy;

  public class Test {

  /**

  * JAVA 動態代理

  * @param args

  */

  public static void main(String[] args) {

  /*

  * test:在測試類中創建動態代理對象

  *

  * 首先獲取一個業務接口的實現對象

  * 獲取一個InvocationHandler實現此處是HelloWorldHandler對象

  * 創建動態代理對象

  * 通過動態代理對象調用sayHello()和sayHelloWithReturnValue()方法此時會在原始對象HelloWorldImpl sayHello()和sayHelloWithReturnValue()方法前後輸出兩句字符串

  */

  HelloWorld hw = new HelloWorldImpl();

  InvocationHandler handler = new HelloWorldHandler(hw);

  HelloWorld proxy = (HelloWorld) ProxynewProxyInstance(hwgetClass()getClassLoader()hwgetClass()getInterfaces()handler);

  proxysayHello();

  String str = proxysayHelloWithReturnValue();

  Systemoutprintln(str = + str);

  Systemoutprintln(\n\n);

  /*

  * test:從代理類中獲取動態代理對象

  */

  HelloWorldHandler handler = new HelloWorldHandler();

  HelloWorld proxy = (HelloWorld)handlernewProxy(new HelloWorldImpl());

  proxysayHello();

  String str = proxysayHelloWithReturnValue();

  Systemoutprintln(str = + str);

  }

  }


From:http://tw.wingwit.com/Article/program/Java/hx/201311/25940.html
  • 上一篇文章:

  • 下一篇文章:
  • 推薦文章
    Copyright © 2005-2022 電腦知識網 Computer Knowledge   All rights reserved.