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

Groovy探索之MOP 九 Interceptor 一

发布时间:2020-12-14 17:08:48 所属栏目:大数据 来源:网络整理
导读:?????????????????? Groovy探索之MOP 九 Interceptor 一 ? ? 近几年以来,AOP(面向方面的编程)得到了广泛的应用,我们把它应用到例如打印日志、权限控制等各个方面。而在实现AOP的时候,我们一般都借助于工具,如Spring AOP等等。 当然,我们借助于工具一

?????????????????? Groovy探索之MOP 九 Interceptor 一

?

?

近几年以来,AOP(面向方面的编程)得到了广泛的应用,我们把它应用到例如打印日志、权限控制等各个方面。而在实现AOP的时候,我们一般都借助于工具,如Spring AOP等等。

当然,我们借助于工具一般都用在实现系统级的AOP上,这种实现一般都要借助于配置文档来实现。

当我们需要实现较小范围的AOP的时候,比如对有限几个类的某些方法进行AOP,这时候,我们一般不希望使用工具。原因可能是第一工具不够灵活第二需要做繁琐的配置工作。这时候,我们需要自己来实现AOP的方方面面。

Java语言一般来说,有两种方法来实现自己的AOP技术:一是通过反射技术来实现;二是使用动态代理。这两种方法在这里就不多说,但实现起来都比较复杂。

在Groovy语言中,我们可以通过Interceptor(拦截器)来实现AOP技术。使用Interceptor来实现AOP技术,技术难度就小多了,而且更加的灵活。

本系列的文字,正是来谈谈Interceptor技术的方方面面,从它怎么样拦截一个方法起,一直讲到怎么使用它来灵活多变的使用我们自己的AOP。

还是从一个简单的例子说起吧。比如,我们有如下的一个类:

?

class HelloWorld {

???

??? def hello()

??? {

?????? println 'hello'

??? }

?

}

?

我们现在要拦截它的"hello"方法。

首先,我们要实现自己的拦截器类,在Groovy语言的编程中,实现自己的拦截器类很简单,就是要实现Interceptor接口,而该接口只有简简单单的三个需要实现的方法。如下所示:

?

class SampleInterceptor implements Interceptor{

???

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

??? {

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

?????? {

?????????? println 'before invoke hello'

?????? }

??? }

??? boolean doInvoke(){ true }

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

?????? Object result){

?????????? result

??? }

?

?

}

?

从上面的实例代码可以看出,我们的拦截器类需要实现三个方法,即"beforeInvoke"方法,用来做调用方法之前的动作;"doInvoke"方法,决定是否调用需要拦截的方法;"afterInvoke"方法,用来做调用方法之后的动作。

上面的实例代码中,我们拦截了HelloWorld类的"hello"方法,在调用该方法之前打印了"before invoke hello"这样的字样。

现在,我们就可以来测试我们的第一个拦截器类了:

?

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

??? ?

??? proxy.interceptor= new SampleInterceptor()

?????? proxy.use{

?????????? def helloworld= new HelloWorld()

?????????? helloworld.hello()

??? }

?

拦截器的使用也十分简单,首先是实例化一个"ProxyMetaClass"类的实例"proxy",然后把我们的拦截器类的实例赋给"proxy"对象的"interceptor"。最后,就是在"proxy"对象的"use"方法里实例化需要被拦截的类,调用它的方法。

上面代码的结果为:

before invoke hello

hello

?

这样就完成了一个简单的拦截任务。

我们初步认识了我们自己的一个简单的拦截器以后,就需要深入的理解拦截器的方方面面了。

首先,我们使用拦截器拦截了一个类的某个方法,就可以实际调用该方法,就像上面的例子一样,也可以实际上不调用该方法。如下所示:

?

class SampleInterceptor implements Interceptor{

???

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

??? {

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

?????? {

?????????? println 'before invoke hello'

?????? }

?????? object

??? }

??? boolean doInvoke(){ false }

?

??? Object afterInvoke(Object object,

?????? Object result){

?????????? result

??? }

?

}

?

还是上面的拦截器类,为了不调用我们所要拦截的方法,我们做了一点改动。首先,方法"doInvoke"的返回值为"false",它能决定不调用所要拦截的方法。如果不调用所要拦截的方法,那么"beforeInvoke"方法一定要有返回值,如上面的代码返回"object"。否则会报空指针的违例。

现在,我们还是使用上面的使用过的代码来测试它:

?

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

??? ?

??? proxy.interceptor= new SampleInterceptor()

?????? proxy.use{

?????? ?

?????????? def helloworld= new HelloWorld()

?????????? helloworld.hello()

?????? }

???

运行结果为:

before invoke hello

?

值得注意的是,在上面的例子中,我们都使用了"beforeInvoke"方法作为例子,它是用来在调用被拦截的方法之前做动作,如果要在调用被拦截的方法之后做动作,就要使用到"afterInvoke",用法两者也大体一样。

现在,我们再来看看"beforeInvoke"和"afterInvoke"方法的参数。其中,"object"是被拦截的对象,"methodName"是被拦截的方法名,"arguments"是被拦截方法的参数。下面一并做测试。

首先,我们对上面的"HelloWorld"类做稍微的改动,以便于我们的测试:

?

class HelloWorld {

?

??? def hello(name)

??? {

?????? println "hello,$name!"

??? }

?

}

?

同样,我们也需要改动一下我们的拦截器类:

?

class SampleInterceptor implements Interceptor{

???

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

??? {

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

?????? {

?????????? println "object: $object"

?????????? println "method name: $methodName"

?????????? println "method arguments: $arguments"

?????? }

??? }

??? boolean doInvoke(){ true } //whether or not to invoke the intercepted

?

??? Object afterInvoke(Object object,

?????? Object result){

?????????? result

??? }

?

}

?

最后,我们来测试上面的改动:

?

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

??? ?

??? proxy.interceptor= new SampleInterceptor()

?????? proxy.use{

?????? ?

?????????? def helloworld= new HelloWorld()

?????????? helloworld.hello('world')

??????????

??? }

?

结果为:

object: mop.interceptor.basic.HelloWorld@f0eed6

method name: hello

method arguments: {"world"}

hello,world!

?

最后,我们还要看看"afterInvoke"方法的"result"参数,它是被拦截方法的返回值,在上面的例子中,我们都是直接把该参数返回了,表示我们不改变被拦截方法的返回值。说到这里,我们就想到了,当然,我们可以改变被拦截方法的返回值。如下所示:

?

class HelloWorld {

?

??? def test()

??? {

?????? 'hello'

??? }

?

}

?

我们来修改一下拦截器类:

?

class SampleInterceptor implements Interceptor{

???

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

??? {

??? }

??? boolean doInvoke(){ true }

?

??? Object afterInvoke(Object object,

?????? Object result){

??????????

?????? if(methodName == 'test')

?????? {

?????????? println result

?????????? result = 'world'

?????? }

??????

?????? result

??? }

?

}

?

最后是测试:

def proxy= ProxyMetaClass.getInstance( HelloWorld )

??? ?

??? proxy.interceptor= new SampleInterceptor()

?????? proxy.use{

?????? ?

?????????? def helloworld= new HelloWorld()

??????????

?????????? def result = helloworld.test()

??????????

?????????? println 'after interceptor,the result: '+result

??????????

?????? }

???

?

结果为:

hello

after interceptor,the result: world

(编辑:李大同)

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

    推荐文章
      热点阅读