<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 :: 首頁 ::  :: 聯系 :: 聚合  :: 管理
    AOP:Aspect Oriented Programming,意為面向切面/局部的程序設計。它是面向對象的程序設計的一種延伸。

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

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

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


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

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


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


    動態代理類:Proxy 被代理的接口 InvocationHandler實現類 代理類

         實際上的調用關系可以用下面的流程圖來表示:

    Proxy.newProxyInstance

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

    XxxxInterface.calledMethod

    $ProxyN.calledMethod

    InvocationHandler.invoke

    method.invoke(obj, args)

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



    用Java Proxy實現AOP容器
    下面我們使用Java Proxy來實現一個簡單的AOP容器。
    文件列表:
    文件名 說明
    AopInvocationHandlerImpl.java 該類實現了java.lang.reflect.InvocationHandler接口,我們通過它記錄LOG信息
    AopContainer.java 簡單的AOP容器,通過它把IDoBusiness與AopInvocationHandlerImpl關聯起來
    IDoBusiness.java 邏輯處理接口
    DoBusiness.java 邏輯處理實現類
    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個參數(第一個參數為被代理的接口,第二個參數為被代理的類實例)
    第二個getBean方法只有一個參數,就是類的實例。該類必須實現1個以上的接口。本文的例子并沒有使用到該方法,所以這里順便介紹一下它的使用方法。比如有一個類HelloWorld實現了接口IHelloWorld1和IHelloWorld2,那么可以通過
    HelloWorld helloWorld = new HelloWorld();
    IHelloWorld1 helloWorld1 = (IHelloWorld1)AopContainer.getBean(helloWorld);
    //或
    IHelloWorld2 helloWorld2 = (IHelloWorld2)AopContainer.getBean(helloWorld);
    調用。當然很多時候都不會直接用new HelloWorld()生成HelloWorld實例,這里為了簡便,就直接用new生成HelloWorld實例了。

    實現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方法的第一個參數為代理類,在我們這個例子里為java.lang.reflect.Proxy類的一個實例。第二個參數Method,為被代理的接口的方法調用(實際上是自動生成代理類的方法調用),第三個方法為方法調用的參數。
    我們通過在AopInvocationHandlerImpl.invoke方法里的method.invoke(bizPojo, args)來調用bizPojo類的與被代理接口的同名方法。這里,bizPojo必須實現了被代理的接口。
    在我們的例子里,我們在實際上被調用的業務邏輯方法的前后輸出了日志信息。

    實際上的邏輯處理類。該類實現了被代理的接口: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();
         }

    }

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

     

    轉載:http://hi.baidu.com/e9151/blog/item/9c8d772be0319d305243c130.html

    主站蜘蛛池模板: 成人无码WWW免费视频| 亚洲免费无码在线| 99在线精品免费视频九九视| 亚洲精品狼友在线播放| 两性色午夜视频免费播放| AV在线亚洲男人的天堂| 国产特黄特色的大片观看免费视频| 亚洲?V无码乱码国产精品| 黄页网址大全免费观看12网站| 国产精品冒白浆免费视频| 免费观看又污又黄在线观看| 四虎国产精品免费久久影院| 污网站在线观看免费| 亚洲国产小视频精品久久久三级| 人人爽人人爽人人片A免费 | 四虎影视免费在线| 亚洲国产AV一区二区三区四区 | 久久久久亚洲?V成人无码| EEUSS影院WWW在线观看免费| 亚洲中文字幕无码久久2017| 精品国产免费一区二区三区香蕉| 亚洲国产二区三区久久| 在线观看免费高清视频| 99亚洲精品卡2卡三卡4卡2卡| 亚洲片一区二区三区| 日本视频免费高清一本18| 亚洲天堂一区二区三区四区| 麻豆精品国产免费观看| 国产免费一级高清淫曰本片| 亚洲美女aⅴ久久久91| 成年轻人网站色免费看| 国产精品青草视频免费播放| 亚洲av日韩综合一区在线观看| 国产大片线上免费观看| 国产亚洲视频在线| 亚洲精品高清国产麻豆专区| 国产福利免费在线观看| 暖暖在线视频免费视频| 日韩欧美亚洲中文乱码| 久久久久久亚洲Av无码精品专口| 免费观看大片毛片|