<rt id="bn8ez"></rt>
<label id="bn8ez"></label>

  • <span id="bn8ez"></span>

    <label id="bn8ez"><meter id="bn8ez"></meter></label>

    沙漠中的魚

    欲上天堂,先下地獄
    posts - 0, comments - 56, trackbacks - 0, articles - 119
      BlogJava :: 首頁 ::  :: 聯(lián)系 :: 聚合  :: 管理
    AOP:Aspect Oriented Programming,意為面向切面/局部的程序設(shè)計。它是面向?qū)ο蟮某绦蛟O(shè)計的一種延伸。

    本文試圖通過使用Java本身的動態(tài)屬性,來實現(xiàn)一個具有簡單的AOP功能的容器。

    開始理解起來可能比較費勁,但我們可以通過一個通俗說明來這樣理解AOP的概念,就是使用AOP可以不用修改原有的代碼,而可以追加新的功能。

    比如,我們用AOP實現(xiàn)了用戶登陸(判斷ID與密碼是否正確)功能,現(xiàn)在我們要求在用戶登陸時用LOG記錄用戶登陸的情況。一般的做法是直接修改已有的登陸邏輯代碼,但使用AOP,可以不用修改原有的代碼而完成此功能。


    本文試圖通過使用Java本身的動態(tài)代理功能,來實現(xiàn)一個具有簡單的AOP功能的容器。從而幫助大家對AOP有個大概的認(rèn)識。

    Java動態(tài)代理功能
    首先,我們簡單介紹一下Java動態(tài)代理功能。JAVA的動態(tài)代理功能主要通過java.lang.reflect.Proxy類與java.lang.reflect.InvocationHandler接口完成,這里正是通過它們實現(xiàn)一個簡單的AOP容器的。其實,像JBoss AOP等其他動態(tài)AOP框架也都是通過Proxy和InvocationHandler來實現(xiàn)的。


    • Java從JDK1.3開始提供動態(tài)代理(Java Proxy)功能。
    • 所謂動態(tài)代理,即通過代理類:Proxy的代理,接口和實現(xiàn)類之間可以不直接發(fā)生聯(lián)系,而可以在運行期(Runtime)實現(xiàn)動態(tài)關(guān)聯(lián)。
    • AOP(Aspect Oriented Programming):面向切面編程,其中的一種實現(xiàn)方法便是用Proxy來實現(xiàn)的。
    • Java Proxy只能代理接口,不能代理類。
    • Java Proxy功能主要通過java.lang.reflect.Proxy類與java.lang.reflect.InvocationHandler接口實現(xiàn)。
    • java.lang.reflect.Proxy (代理類) > ProxyInterface(被代理的接口)   > InvocationHandler(關(guān)聯(lián)類)> Class(可以在InvocationHandler中被調(diào)用)。它們之間的關(guān)系可以用下面的流程圖來表示:


    動態(tài)代理類:Proxy 被代理的接口 InvocationHandler實現(xiàn)類 代理類

         實際上的調(diào)用關(guān)系可以用下面的流程圖來表示:

    Proxy.newProxyInstance

    XxxxInterface xx = $ProxyN(N=0,1,2…)

    XxxxInterface.calledMethod

    $ProxyN.calledMethod

    InvocationHandler.invoke

    method.invoke(obj, args)

    obj.calledMethod
    1. Proxy. newProxyInstance的參數(shù):必須傳送以下3個參數(shù)給Proxy. newProxyInstance方法:ClassLoader,Class[],InvocationHandler。其中參數(shù)2為被代理的接口 Class,參數(shù)3為實現(xiàn)InvocationHandler接口的實例。
    2. 可以通過Proxy. newProxyInstance方法得到被代理的接口的一個實例(instance),該實例由newProxyInstance方法動態(tài)生成,并實現(xiàn)了該接口。
    3. 當(dāng)程序顯示調(diào)用接口的方法時,其時是調(diào)用該實例的方法,此方法又會調(diào)用與該實例相關(guān)聯(lián)InvocationHandler的invoke方法。
    4. 這樣我們可以在InvocationHandler.invoke方法里調(diào)用某些處理邏輯或真正的邏輯處理實現(xiàn)類。



    用Java Proxy實現(xiàn)AOP容器
    下面我們使用Java Proxy來實現(xiàn)一個簡單的AOP容器。
    文件列表:
    文件名 說明
    AopInvocationHandlerImpl.java 該類實現(xiàn)了java.lang.reflect.InvocationHandler接口,我們通過它記錄LOG信息
    AopContainer.java 簡單的AOP容器,通過它把IDoBusiness與AopInvocationHandlerImpl關(guān)聯(lián)起來
    IDoBusiness.java 邏輯處理接口
    DoBusiness.java 邏輯處理實現(xiàn)類
    TestAop.java 測試類

    簡單的AOP容器:
    AopContainer.java
    package com.test.aop.framework;

    import java.lang.reflect.Proxy;

    /**
    * A Simple AOP Container
    *
    */

    public class AopContainer {
        public static <T> T getBean(Class<T> interfaceClazz, final T obj) {
             assert interfaceClazz.isInterface();
            
            return (T) Proxy.newProxyInstance(interfaceClazz.getClassLoader(),
                    new Class[] { interfaceClazz }, new AopInvocationHandlerImpl(obj));
         }

        public static Object getBean(final Object obj) {
            return Proxy.newProxyInstance(obj.getClass().getClassLoader(),
                     obj.getClass().getInterfaces(), new AopInvocationHandlerImpl(obj));
         }
    }
    第一個getBean方法通過2個參數(shù)(第一個參數(shù)為被代理的接口,第二個參數(shù)為被代理的類實例)
    第二個getBean方法只有一個參數(shù),就是類的實例。該類必須實現(xiàn)1個以上的接口。本文的例子并沒有使用到該方法,所以這里順便介紹一下它的使用方法。比如有一個類HelloWorld實現(xiàn)了接口IHelloWorld1和IHelloWorld2,那么可以通過
    HelloWorld helloWorld = new HelloWorld();
    IHelloWorld1 helloWorld1 = (IHelloWorld1)AopContainer.getBean(helloWorld);
    //或
    IHelloWorld2 helloWorld2 = (IHelloWorld2)AopContainer.getBean(helloWorld);
    調(diào)用。當(dāng)然很多時候都不會直接用new HelloWorld()生成HelloWorld實例,這里為了簡便,就直接用new生成HelloWorld實例了。

    實現(xiàn)InvocationHandler接口的中間類:
    AopInvocationHandlerImpl.java
    package com.test.aop.framework;

    import java.lang.reflect.InvocationHandler;
    import java.lang.reflect.Method;

    public class AopInvocationHandlerImpl implements InvocationHandler {
        private Object bizPojo;
        
        public AopInvocationHandlerImpl(Object bizPojo) {
             this.bizPojo = bizPojo;
         }

        /*
         * (non - Javadoc)
         *
         * @see java.lang.reflect.InvocationHandler#invoke(java.lang.Object,
         *       java.lang.reflect.Method, java.lang.Object[])
         */

        public Object invoke(Object proxy, Method method, Object[] args)
                throws Throwable {
             Object o = null;
            try {
                 System.out.println("Start:" + method.getName());
                 o = method.invoke(bizPojo, args);
                 System.out.println("End:" + method.getName());
             } catch (Exception e) {
                 e.printStackTrace();
                 System.out.println("Exception Occured!" + e.getMessage());
                // excetpion handling.
             }
            return o;
         }
    }
    AopInvocationHandlerImpl.invoke方法的第一個參數(shù)為代理類,在我們這個例子里為java.lang.reflect.Proxy類的一個實例。第二個參數(shù)Method,為被代理的接口的方法調(diào)用(實際上是自動生成代理類的方法調(diào)用),第三個方法為方法調(diào)用的參數(shù)。
    我們通過在AopInvocationHandlerImpl.invoke方法里的method.invoke(bizPojo, args)來調(diào)用bizPojo類的與被代理接口的同名方法。這里,bizPojo必須實現(xiàn)了被代理的接口。
    在我們的例子里,我們在實際上被調(diào)用的業(yè)務(wù)邏輯方法的前后輸出了日志信息。

    實際上的邏輯處理類。該類實現(xiàn)了被代理的接口:IDoBusiness。
    DoBusiness.java
    package com.test.aop.framework;

    /**
    * A business class
    *
    */

    public class DoBusiness implements IDoBusiness {
        public void printNothing() {
             System.out.println("Just Say Hello!");
         }
        
        public void throwException() {
            throw new RuntimeException("throw Exception from DoBusiness.throwException()");
         }

    }

    被代理的接口定義:
    IDoBusiness.java
    package com.test.aop.framework;

    /**
    * interface for business logic process
    *
    */

    public interface IDoBusiness {
        public void printNothing();
        public void throwException();
    }

    測試類:
    TestAop.java
    package com.test.aop.framework;


    /**
    * Test AOP
    *
    */

    public class TestAop {

        /**
         * @param args
         */

        public static void main(String[] args) {
             DoBusiness doBusiness = new DoBusiness();
             IDoBusiness idoBusiness = AopContainer.getBean(IDoBusiness.class, doBusiness);
             idoBusiness.printNothing();
            
             idoBusiness.throwException();
         }

    }

    總結(jié):
    本文通過Java Proxy實現(xiàn)了一個簡單地AOP容器。也簡單地展示了AOP的基本實現(xiàn)原理,實際上可以以此為基礎(chǔ)實現(xiàn)一個功能完善的AOP容器。

     

    轉(zhuǎn)載:http://hi.baidu.com/e9151/blog/item/9c8d772be0319d305243c130.html

    主站蜘蛛池模板: 1000部拍拍拍18勿入免费视频下载 | 18禁成人网站免费观看| 黄色三级三级免费看| 亚洲综合亚洲国产尤物| 在线日韩日本国产亚洲| 免费观看四虎精品国产永久| 91香蕉成人免费网站| 男人进去女人爽免费视频国产| 黄床大片30分钟免费看| 亚洲欧洲免费无码| 亚洲国产精品成人综合色在线婷婷| 亚洲不卡中文字幕无码| 中文字幕亚洲日本岛国片| 国产一级高清免费观看| 免费黄色大片网站| 特级做A爰片毛片免费69| **aaaaa毛片免费| 99国产精品视频免费观看| 18禁超污无遮挡无码免费网站| japanese色国产在线看免费| 在线视频亚洲一区| 亚洲国产精品无码久久98| 亚洲一区二区三区国产精华液| 亚洲无砖砖区免费| 亚洲日本在线免费观看| 亚洲免费黄色网址| 亚洲大尺码专区影院| 亚洲国产美女视频| 亚洲av永久综合在线观看尤物| 亚洲欧洲日产国码二区首页| 亚洲美女一区二区三区| 亚洲视频免费在线看| 亚洲福利一区二区| 亚洲春色另类小说| 亚洲高清中文字幕免费| 在线亚洲午夜片AV大片| 亚洲AV永久无码精品一福利| 国产精品亚洲AV三区| 免费大片av手机看片高清| 一级毛片正片免费视频手机看| 一级毛片aaaaaa视频免费看|