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

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

你可能感兴趣的:(groovy)