加入收藏 | 设为首页 | 会员中心 | 我要投稿 李大同 (https://www.lidatong.com.cn/)- 科技、建站、经验、云计算、5G、大数据,站长网!
当前位置: 首页 > 大数据 > 正文

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

发布时间:2020-12-14 17:08:21 所属栏目:大数据 来源:网络整理
导读:??????? Groovy 探索之 MOP 十三 Interceptor 三( 2 ) ? ? ? 其实,阻止拦截的使用像在《 Groovy 探索之 MOP 十三 Interceptor 三( 1 )》中的最后一个例子那像的使用并不多,更多的是在使用拦截器的客户那里决定是否使用拦截器。还是上一篇的那个例子:

???????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,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,

??? Object[] arguments )

???

??? public Object beforeInvoke( Object object,

??? 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,

??? Object result )

???

??? public Object afterInvoke( Object object,

??? Object[] arguments,Object result ){

?????? proxy.interceptor= null

?????? try{

?????????? result= doAfter(object,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,

?????????? Object[] arguments )

??? {

??????

??? }

???

??? boolean doInvoke()

??? {

?????? true

??? }

???

??? Object doAfter( Object object,

?????????? 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

?

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

(编辑:李大同)

【声明】本站内容均来自网络,其相关言论仅代表作者个人观点,不代表本站立场。若无意侵犯到您的权利,请及时与联系站长删除相关内容!

    推荐文章
      热点阅读