午后星期午

          Java動態代理設計模式

           所謂動態代理類是在運行時生成的class,在生成它時,你必須提供一組interface給它,則動態代理類就宣稱它實現了這些 interface。當然,動態代理類就充當一個代理,你不要企圖它會幫你干實質性的工作,在生成它的實例時你必須提供一個handler,由它接管實際的工作。
            下面通過實例來說明:
            Subject.java 抽象借口:聲明代理對象和真實對象的共同接口
            [java]
            public interface Subject {
            public void doSomething();
            }
            public interface Subject {
            public void doSomething();
            }
            RealSubject.java 真實被tb代理對象
            [java]
            public class RealSubject implements Subject {
            @Override
            public void doSomething() {
            System.out.println("RealSubject.doSomething");
            }
            }
            public class RealSubject implements Subject {
            @Override
            public void doSomething() {
            System.out.println("RealSubject.doSomething");
            }
            }

            DynamicProxy.java 代理對象
            [java]
            import java.lang.reflect.InvocationHandler;
            import java.lang.reflect.Method;
            public class DynamicProxy implements InvocationHandler {
            private Object object;
            public DynamicProxy(Object object) {
            this.object = object;
            }
            @Override
            public Object invoke(Object proxy, Method method, Object[] args)throws Throwable {
            System.out.println("Before Invoke ! method : " + method);
            //我們可以再代理方法調用前后添加功能
            Object result = method.invoke(object, args);
            System.out.println("object : " + object + " result : " + result + " args : " + args);
            System.out.println("After Invoke !");
            return result;
            }
            }
            import java.lang.reflect.InvocationHandler;
            import java.lang.reflect.Method;
            public class DynamicProxy implements InvocationHandler {
            private Object object;
            public DynamicProxy(Object object) {
            this.object = object;
            }
            @Override
            public Object invoke(Object proxy, Method method, Object[] args)throws Throwable {
            System.out.println("Before Invoke ! method : " + method);
            //我們可以再代理方法調用前后添加功能
            Object result = method.invoke(object, args);
            System.out.println("object : " + object + " result : " + result + " args : " + args);
            System.out.println("After Invoke !");
            return result;
            }
            }
            Client.java 測試
            [java]
            import java.lang.reflect.InvocationHandler;
            import java.lang.reflect.Proxy;
            public class Client {
            public static void main(String[] args) throws Exception {
            //創建目標對象,也就是被代理對象
            RealSubject realSubject = new RealSubject();
            //將目標對象交給代理
            InvocationHandler handler = new DynamicProxy(realSubject);
            // Class proxyClass = Proxy.getProxyClass(Subject.class.getClassLoader()
            // , new Class[]{Subject.class});
            // Subject subject = (Subject)proxyClass.getConstructor(new Class[]{InvocationHandler.class})
            // .newInstance(new Object[]{handler});
            //返回代理對象,相當于上面兩句
            Subject subject = (Subject) Proxy.newProxyInstance(handler.getClass().getClassLoader(),
            realSubject.getClass().getInterfaces(),
            handler);
            //叫代理對象去doSomething(),其實在代理對象中的doSomething()中還是會
            //用handler來調用invoke(proxy, method, args) 參數proxy為調用者subject(this),
            //method為doSomething(),tb參數為方法要傳入的參數,這里沒有
            subject.doSomething();
            }
            }
            import java.lang.reflect.InvocationHandler;
            import java.lang.reflect.Proxy;
            public class Client {
            public static void main(String[] args) throws Exception {
            //創建目標對象,也就是被代理對象
            RealSubject realSubject = new RealSubject();
            //將目標對象交給代理
            InvocationHandler handler = new DynamicProxy(realSubject);
            // Class proxyClass = Proxy.getProxyClass(Subject.class.getClassLoader()
            // , new Class[]{Subject.class});
            // Subject subject = (Subject)proxyClass.getConstructor(new Class[]{InvocationHandler.class})
            // .newInstance(new Object[]{handler});
            //返回代理對象,相當于上面兩句
            Subject subject = (Subject) Proxy.newProxyInstance(handler.getClass().getClassLoader(),
            realSubject.getClass().getInterfaces(),
            handler);
            //叫代理對象去doSomething(),其實在代理對象中的doSomething()中還是會
            //用handler來調用invoke(proxy, method, args) 參數proxy為調用者subject(this),
            //method為doSomething(),參數為方法要傳入的參數,這里沒有
            subject.doSomething();
            }
            }
            打印結果:
            Before Invoke ! method : public abstract void Subject.doSomething()
            RealSubject.doSomething
            object : RealSubject@ec6b00 result : null args : null
            After Invoke !
            注意:
            Java動態代理涉及到的兩個類:
            InvocationHandler:該接口中僅定義了一個Object : invoke(Object proxy, Method method, Object[] args);參數proxy指代理類,method表示被代理的方法,args為method中的參數數組,返回值Object為代理實例的方法調用返回的值。這個抽象方法在代理類中動態實現。
            Proxy:所有動態代理類的父類,提供用于創建動態代理類和實例的靜態方法。

          posted on 2013-12-31 14:07 午后星期午 閱讀(119) 評論(0)  編輯  收藏 所屬分類: Java

          主站蜘蛛池模板: 阿坝县| 水城县| 鸡泽县| 伊春市| 郑州市| 遂昌县| 达孜县| 沛县| 凤冈县| 乐昌市| 平武县| 承德县| 崇义县| 济阳县| 南城县| 株洲县| 邵阳县| 宜宾市| 曲阜市| 淮北市| 阜城县| 涿州市| 保德县| 都匀市| 平阳县| 通道| 大埔县| 平和县| 察哈| 平原县| 观塘区| 宿迁市| 资阳市| 彩票| 梅州市| 蓬安县| 贡山| 富川| 同心县| 西和县| 沧州市|