Groovy探索之MOP 十三 Interceptor 三(2)

       Groovy探索之MOP 十三 Interceptor 三(2

 

 

 

其实,阻止拦截的使用像在《Groovy探索之MOP 十三 Interceptor 三(1)》中的最后一个例子那像的使用并不多,更多的是在使用拦截器的客户那里决定是否使用拦截器。还是上一篇的那个例子:

 

class Hello {

   

    def hello(name)

    {

       "hello,$name"

    }

 

}

 

 

我们现在明确的把类中所有的方法进行拦截,拦截器如下:

 

class AllInterceptor implements Interceptor{

   

 

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

      

       println "the function-$methodName is intercepted"

      

    }

   

    boolean doInvoke(){ true }

   

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

           Object result){

       result

    }

 

}

 

 

在上面的拦截器中,我们在“beforeInvoke”方法中拦截了被拦截对象中的所有方法,打印出哪个方法被拦截的提示出来。

比如,我们做如下的测试代码:

 

 

        def proxy= ProxyMetaClass.getInstance( Hello )

     

       proxy.interceptor= new AllInterceptor()

       

       proxy.use{

           def hello = new Hello()

           hello.hello('World')

       }

 

 

 

运行结果为:

the function-ctor is intercepted

the function-hello is intercepted

 

表示已经有了两个方法被拦截。现在,我们的客户端不想拦截“hello”方法,在这里我们就可以使用阻止拦截了:

 

        def proxy= ProxyMetaClass.getInstance( Hello )

     

       proxy.interceptor= new AllInterceptor()

       

       proxy.use{

           def hello = new Hello()

           hello.&hello('World')

       }

 

 

运行结果为:

the function-ctor is intercepted

 

 

这样就没有对“hello”方法进行拦截。

我们还是需要回忆一下上一篇中遇到的嵌套拦截的问题,即在拦截器中又调用了需要被拦截的那个方法,形成了嵌套拦截的问题。我们在上一篇中的解决方法是使用“&”标识符进行阻止拦截。使用“&”标识符毕竟只能阻止少量的方法进行嵌套拦截,在实际的使用中不是很方便,为了解决这个问题,我们也有一个一劳永逸的解决办法。即我们可以创建一个阻止嵌套拦截器类,让继承它的所有拦截器具备有阻止嵌套拦截的能力。

这个基类如下:

 

abstract class UninterceptedInterceptor implements Interceptor{

    def proxy= null

   

    abstract Object doBefore( Object object, String methodName,

    Object[] arguments )

   

    public Object beforeInvoke( Object object, String methodName,

    Object[] arguments ){

       proxy.interceptor= null

       def result

       try{

           result= doBefore(object, methodName, arguments)

       }catch(Exception e){

       throw e

       }finally{

           proxy.interceptor= this

       }

       result

    }

   

    abstract boolean doInvoke()

   

    abstract Object doAfter( Object object, String methodName, Object[] arguments,

    Object result )

   

    public Object afterInvoke( Object object, String methodName,

    Object[] arguments, Object result ){

       proxy.interceptor= null

       try{

           result= doAfter(object, methodName, arguments, result)

       }catch(Exception e){

       throw e

       }finally{

           proxy.interceptor= this

       }

       result

  }

 

}

 

这个基类很简单,可以放到我们的工具包里去。我们只看“beforeInvoke”方法,思想就是,我们的拦截动作都放在“doBefore”方法里,同时,在执行“doBefore”方法的时候,我们使用如下的语句将拦截器去掉:

proxy.interceptor= null

当“doBefore”方法完了以后,我们再把拦截器加上,使用下面的语句:

proxy.interceptor= this

 

这样,我们需要进行嵌套拦截的类就继承该类,如下:

 

class MyInterceptor extends UninterceptedInterceptor{

   

    Object doBefore( Object object, String methodName,

           Object[] arguments )

    {

      

    }

   

    boolean doInvoke()

    {

       true

    }

   

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

           Object result )

    {

       if(methodName == 'hello')

       {

           result = new Hello().hello('log')+'/n'+result

       }

       result

    }

 

}

 

 

这个类就更简单了,在它里面进行了拦截方法的嵌套调用,形如下面的语句:

if(methodName == 'hello')

       {

           result = new Hello().hello('log')+'/n'+result

    }

 

拦截了“hello”方法,却在里面又进行“hello”方法的调用,一个很明显的嵌套调用。

最后,我们来写点代码测试这个阻止拦截的拦截器:

 

      def proxy= ProxyMetaClass.getInstance( Hello )

     

       proxy.interceptor = new MyInterceptor()

     

      proxy.interceptor.proxy = proxy

       

       proxy.use{

           def hello = new Hello()

           println hello.hello('World')

       }

   

 

这也和其他的测试代码大致相似,唯一不同的是下面的语句:

proxy.interceptor.proxy = proxy

 

它需要我们给Interceptor对象的“proxy”属性赋值,这在其他的测试代码里是没有的。运行结果为:

hello,log

hello,World

 

的确起到了阻止拦截的效果。

展开阅读全文

没有更多推荐了,返回首页