JAVA動態(tài)代理實現(xiàn)方法

字號:

在目前的Java開發(fā)包中包含了對動態(tài)代理的支持,但是其實現(xiàn)只支持對接口的的實現(xiàn)。
    其實現(xiàn)主要通過是java.lang.reflect.Proxy類和java.lang.reflect.InvocationHandler接口。
     Examda提示: Proxy類主要用來獲取動態(tài)代理對象,InvocationHandler接口用來約束調用者實現(xiàn),如下,HelloWorld接口定義的業(yè)務方法,HelloWorldImpl是HelloWorld接口的實現(xiàn),HelloWorldHandler是 InvocationHandler接口實現(xiàn)。代碼如下:
    業(yè)務接口:
    public interface HelloWorld {
    void sayHelloWorld() ;
    }
    業(yè)務接口實現(xiàn):
    public class HelloWorldImpl implements HelloWorld {
    public void sayHelloWorld() {
    System.out.println("Hello World!");
    }
    }
    InvocationHandler實現(xiàn),需要在接口方法調用前后加入一部份處理工作,這里僅僅在方法調用前后向后臺輸出兩句字符串,其代碼如下:
     import java.lang.reflect.InvocationHandler;
    import java.lang.reflect.Method;
    public class HelloWorldHandler implements InvocationHandler {
    //要代理的原始對象
    private Object objOriginal;
    /**
    * 構造函數(shù)。
    * @param obj Examda提示: 要代理的原始對象。
    */
    public HelloWorldHandler(Object obj) {
    this.objOriginal = obj ;
    }
    public Object invoke(Object proxy, Method method, Object[] args)
    throws Throwable {
    Object result ;
    //方法調用之前
    doBefore();
    //調用原始對象的方法
    result = method.invoke(this.objOriginal ,args);
    //方法調用之后
    doAfter();
    return result ;
    }
    private void doBefore() {
    System.out.println("before method invoke!");
    }
    private void doAfter() {
    System.out.println("after method invoke!");
    }
    }
    測試代碼:
    import java.lang.reflect.InvocationHandler;
    import java.lang.reflect.Proxy;
    public class Test {
    public static void main(String[] args) {
    HelloWorld hw = new HelloWorldImpl();
    InvocationHandler handler = new HelloWorldHandler(hw);
    HelloWorld proxy = (HelloWorld) Proxy.newProxyInstance(
    hw.getClass().getClassLoader(),
    hw.getClass().getInterfaces(),
    handler);
    proxy.sayHelloWorld();
    }
    }
    Ø 首先獲取一個業(yè)務接口的實現(xiàn)對象;
    Ø 獲取一個InvocationHandler實現(xiàn),此處是HelloWorldHandler對象;
    Ø 創(chuàng)建動態(tài)代理對象;
    Ø 通過動態(tài)代理對象調用sayHelloWorld()方法,此時會在原始對象HelloWorldImpl. sayHelloWorld()方法前后輸出兩句字符串。
    運行測試類輸出如下:
    before method invoke!
    Hello World!
    after method invoke!
    此處Test類中的方法調用代碼比較多,在我們的實際應用中可以通過配置文件來來簡化客戶端的調用實現(xiàn)。另外也可以通過動態(tài)代理來實現(xiàn)簡單的AOP。