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

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

发布时间:2020-12-14 17:08:23 所属栏目:大数据 来源:网络整理
导读:? ???????????? ? Groovy 探索之 MOP 十三 Interceptor 三( 1 ) ? ? ? 本篇的“ Interceptor ”,主要是来说说拦截器的阻止拦截的问题,这个问题是我们自定义拦截器时经常要遇到的挑战之一。 与阻止拦截很近的一个意思是不拦截,即我们可以拦截某个方法,

?

?????????????Groovy探索之MOP 十三 Interceptor 三(1

?

?

?

本篇的“Interceptor”,主要是来说说拦截器的阻止拦截的问题,这个问题是我们自定义拦截器时经常要遇到的挑战之一。

与阻止拦截很近的一个意思是不拦截,即我们可以拦截某个方法,但我们不对拦截做任何实质性的动作,即我们简单的将拦截的动作放行。这是一种被动的不拦截行为。而我们的阻止拦截却更为主动一些,即不让拦截器拦截到某个方法。

下面,我们将分别就放行拦截和阻止拦截来举例说明。

首先,我们还是设计一个需要被拦截的类来:

?

class Foo {

???

??? def foo()

??? {

?????? println 'foo'

??? }

???

??? def bar()

??? {

?????? println 'bar'

??? }

?

}

?

假设我们不想拦截“bar”方法,只想拦截“foo”方法,则我们可以这样设计拦截器:

?

?

class NoBarInterceptor implements Interceptor{

???

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

?????? if(methodName == 'foo')

?????? {

?????????? println 'interceptor the function: foo'

?????? }

??? }

???

??? boolean doInvoke(){ true }

???

??? Object afterInvoke(Object object,Object[] arguments,

?????????? Object result){

?????? result

??? }

?

}

?

在代码中,我们只拦截了方法名为“foo”的方法,对其他方法则未做处理,即放行了。我们来写一点测试代码:

?

??? ? ? def proxy= ProxyMetaClass.getInstance( Foo )

??? ?

?????? proxy.interceptor= new NoBarInterceptor()

?????? proxy.use{

?????? def f= new Foo()

?????????? f.foo()

?????????? f.bar()

??? }

?

运行结果为:

interceptor the function: foo

foo

bar

?

?

当然了,如果我们想更加主动的确定对哪些方法放行,则可以这样设计我们的拦截器:

?

class NoMethodInterceptor implements Interceptor{

???

??? def methods

???

??? Object beforeInvoke(Object object,Object[] arguments){

?????? if(!(methodName in this.methods))

?????? {

?????????? println "before invoking $methodName"

?????? }

?????? null

??? }

???

??? boolean doInvoke(){ true }

???

??? Object afterInvoke(Object object,

?????????? Object result){

?????? result

??? }

?

}

?

在上面的代码中,使用if判断语句对需要拦截的方法做了限制,使得该拦截器不能拦截我们给定的某些方法。一切的逻辑都很简单,所以测试代码在这里也不再给出了,你们可以自己写点测试代码来测试一下。

而阻止拦截的概念则更强一些,即我们强烈的要求对某些方法不做拦截,这样使得拦截器不去拦截它们。比如我们有如下的一个需要被拦截的类:

?

class Hello {

???

??? def hello(name)

??? {

?????? "hello,$name"

??? }

?

}

?

我们需要拦截“hello”方法,并在前面打印一些log信息,我们可能会这样写这个拦截器:

?

class StopInterceptor implements Interceptor{

???

??? Object beforeInvoke(Object object,Object[] arguments){

??????

??? }

???

??? boolean doInvoke(){ true }

???

??? Object afterInvoke(Object object,

?????????? Object result){

?????? if(methodName == 'hello')

?????? {

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

?????? }

?????? result

??? }

?

}

?

我们在拦截器里拦截了“hello”方法,并且在它的返回结果使用“hello”方法添加了一些log记录。现在我们可以写代码来测试它:

?

??? ? ? def proxy= ProxyMetaClass.getInstance( Hello )

??? ?

?????? proxy.interceptor= new StopInterceptor()

?????? proxy.use{

?????????? def hello = new Hello()

?????????? println hello.hello('World')

?????? }

?

运行结果却发现了Exception

Exception in thread "main" java.lang.StackOverflowError

?

并且是堆栈溢出。这是因为下面的语句:

if(methodName == 'hello')

?????? {

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

??? }

?

我们在拦截器里又调用了“hello”方法,这个“hello”方法又被拦截器拦截,然后又调用“hello”方法,然后又被拦截,这样就进入了死循环,导致了堆栈溢出。

那么,我们该怎么解决上面的问题呢?当然是希望拦截器里的“hello”方法不要再被拦截器拦截,解决方法很简单,就是在不希望被拦截的方法前面加上“&”标识符,如上面的语句可以修改为:

if(methodName == 'hello')

?????? {

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

??? }

?

这样,我们再运行上面的测试代码,结果为:

hello,log

hello,World

(编辑:李大同)

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

    推荐文章
      热点阅读