Groovy探索之MOP 十 Interceptor 二

                    Groovy探索之MOP 十 Interceptor 二

 

 

在本系列的《Groovy探索之MOP 九 Interceptor 一》中,我們已經詳細的介紹了一個簡單的攔截器類的方方面面,使得我們初步有了攔截器的基礎。本篇需要在前面的攔截器類的基礎上,進一步用攔截器類來實現我們的AOP編程。

首先,我們在本系列的第一篇中,所攔截的方法都是固定的方法。現在,我們需要把它擴展成由攔截器類的使用者來指定被攔截的方法。

先還是給出需要被攔截的類來:

 

class Foo {

   

    def test1()

    {

       println 'test1'

    }

   

    def test2()

    {

       println 'test2'

    }

   

    def test3()

    {

       println 'test3'

    }

 

}

 

然後來給出我們的攔截器類:

 

class MethodsInterceptor implements Interceptor{

   

    def methods

   

    Object beforeInvoke(Object object, String methodName, Object[] arguments){

       if( methodName in this.methods )

       {

           println "before invoking $methodName"

       }

       null

    }

   

    boolean doInvoke(){ true }

   

    Object afterInvoke(Object object, String methodName, Object[] arguments,

           Object result){

       if( methodName in this.methods )

        {

           println "after invoking $methodName"

       }

       result

    }

}

 

有了上一篇文字的基礎,這個攔截器類就比較好理解了。不同的是,在上一篇文字的攔截器類中,需要攔截的方法是固定的,而這個攔截器所需要攔截的方法卻是由屬性"methods"來確定的。

來看看我們怎麼使用這個攔截器類:

     

      def proxy= ProxyMetaClass.getInstance( Foo )

       proxy.interceptor= new MethodsInterceptor(methods:['test1','test2'])

       proxy.use{

       def f= new Foo()

           f.test1()

           f.test2()

           f.test3()

       }

   

運行結果爲:

before invoking test1

test1

after invoking test1

before invoking test2

test2

after invoking test2

test3

 

 

有了這個客戶給定需要攔截的參數,我們就朝着AOP編程邁進了第一步。

接下來,我們需要該攔截器類不同的類起到攔截作用,這樣,我們就可以說,我們初步的完成了一個簡單的AOP編程。

下面,我們來做一個簡單的幫助類,來使得我們的攔截器可以攔截不同的類:

 

class InterceptorHelper {

   

    def static intercept(Class clzz,methodNames,Closure closure)

    {

       def proxy= ProxyMetaClass.getInstance( clzz )

       proxy.interceptor= new MethodsInterceptor(methods:methodNames)

       proxy.use{

           closure.call()

       }

    }

 

}

 

 

很簡單,該工具類需要我們輸入三個參數:"clzz"需要攔截的對象的類;"methodNames"需要攔截的方法;"closure"調用那些需要攔截的方法。

下面是測試用例:

 

      InterceptorHelper.intercept(Foo,['test1','test2']){

        

         def f = new Foo()

         f.test1()

         f.test2()

         f.test3()

      }

   

運行結果爲:

before invoking test1

test1

after invoking test1

before invoking test2

test2

after invoking test2

test3

 

 

爲了測試上面的工具類是否能夠攔截其他的類,我們特意再做了一個測試,假設有如下的一個類:

 

class Too {

   

    def test1()

    {

       println 'too1'

    }

   

    def test2()

    {

       println 'too2'

    }

 

}

 

 

我們也來測試一下,看看我們的工具類是否能夠攔截這個類:

 

    InterceptorHelper.intercept(Too,['test1','test2']){

        

         def t = new Too()

         t.test1()

         t.test2()

      }

   

 

運行結果爲:

before invoking test1

too1

after invoking test1

before invoking test2

too2

after invoking test2

 

 

可以看到,的確可以攔截不同的類的給定方法了。這樣,我們就向着AOP編程邁出了關鍵性的一步了。以後,我們在實際的編碼過程中,我們可能會對我們的攔截器類以及AOP工具提出各種各樣的要求。但都可以從我們上面的例子擴展開來。

我們可以去試着實現一下:

我們如何實現對我們在客戶端給定的對象實現所有的除構造器和GroovyObject方法外的方法實現攔截。

我們又該如何實現對我們在客戶端給定的對象實現由客戶端給定一些不需要攔截的方法後,攔截其他的方法。

從這樣的各種各樣的要求可以看出,實現我們自己的AOP編程的確可以根據項目中的實際要求,達到方便靈活的目的。

發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章