JAVA動(dòng)態(tài)代理實(shí)現(xiàn)方法

字號(hào):

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