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

Groovy探索之MOP 十四 对Java类使用Groovy语言的MOP

发布时间:2020-12-14 17:08:09 所属栏目:大数据 来源:网络整理
导读:??????? Groovy 探索之 MOP 十四 对 Java 类使用 Groovy 语言的 MOP ? ? ? 既然 Groovy 语言是 Java 语言的扩展,那么我们在使用 Groovy 语言的时候,就很难与 Java 语言真正脱得了干系,那怕我们是在做一个纯 Groovy 语言的项目,如 Grails 项目。我们可能

??????? Groovy探索之MOP 十四 Java类使用Groovy语言的MOP

?

?

?

既然Groovy语言是Java语言的扩展,那么我们在使用Groovy语言的时候,就很难与Java语言真正脱得了干系,那怕我们是在做一个纯Groovy语言的项目,如Grails项目。我们可能在Groovy代码中会用到遗留的Java类和包;也可能是为了性能的原因,我们不得不在Groovy语言中使用到Java类;等等。

如果我们要对于Java类使用Groovy语言的MOP,比如我们想给一个Java类的对象在运行期内添加一个方法。那么我们该怎么办呢?

比如,我们有如下的一个Java类:

?

//Java代码)

public class Foo {

???

??? public String foo()

??? {

?????? return "foo";

??? }

?

}

?

?

我们就可以使用如下的方法在运行期内给它的对象添加一个方法:

?

??? ? //Groovy代码)

??? ? ExpandoMetaClass emc = new ExpandoMetaClass( Foo,false )

??? ?

??? ? emc.hello = {"hello,world!"}

??? ?

??? ? emc.initialize()

?

?

上面的代码用来初始化一个“ExpandoMetaClass”对象,然后添加一个方法,然后将这个对象实例化;这些都跟给Groovy对象在运行期内添加一个方法的过程一样,没有什么好多说的。

接下来,我们的代码就和对Groovy对象的操作不一样了,要使用“Proxy”类来包装我们的Java类对象,如下:

?

??? ? def foo = new groovy.util.Proxy().wrap(new Foo())

?

然后就是给这个对象赋值上面的“ExpandoMetaClass”对象:

?

??? ? foo.setMetaClass(emc)

?

最后,我们就可以测试了:

?

??? ? println foo.hello()

???

运行结果为:

hello,world!

?

同样,对于我们上面的Java类,我们也可以使用我们的自定义拦截器来拦截它的动作:

?

//Groovy代码)

class FooInterceptor implements Interceptor{

???

?????? Object beforeInvoke(Object a_object,String a_methodName,Object[] a_arguments)

?????? {

?????????? if(a_methodName == 'foo')

?????????? {

????????????? println 'before invoking function foo'

?????????? }

?????? }

?????? boolean doInvoke()

?????? {

?????????? return true

?????? }

?????? Object afterInvoke(Object a_object,Object[] a_arguments,Object

??? ??? a_result)

?????? {

?????????? a_result

?????? }

?

}

?

这个拦截器跟我们拦截Groovy类的自定义拦截器是一模一样的。使用这个拦截器的方法也是一样的:

?

??? ? //Groovy代码)

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

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

??? ? proxy.use {

??? ? ? def foo = new Foo()

??? ? ? println foo.foo()

??? ? }

???

?

运行结果为:

before invoking function foo

foo

?

?

最后一个方法是我们可以通过在“MetaClassRegistry”类上注册一个“MetaClass”对象来使用Java类拥有“MetaClass”属性,从而获得MOP能力。

首先,我们需要自定义一个“MetaClass”类,如下:

//Groovy代码)

class FooDelegatingMetaClass extends groovy.lang.DelegatingMetaClass{

???

??? FooDelegatingMetaClass(final Class aclass)

??? {

?????? super(aclass);

?????? initialize()

??? }

???

??? public Object invokeMethod(Object a_object,Object[] a_arguments)

??? {

?????? def result

?????? if(a_methodName == 'test')

?????? {

?????????? result = 'test'

?????? }

?????? else

?????? {

?????????? result = "${super.invokeMethod(a_object,a_methodName,a_arguments)}"

?????? }

??????

?????? result

??????

??? }

?

}

?

这也和其他的自定义“MetaClass”类一样,不同的是我们在对Java类使用的时候,需要在“MetaClassRegistry”类上注册。如下:

?

??? ? //Groovy代码)

??? ? def myMetaClass = new FooDelegatingMetaClass(Foo.class)

??? ? def invoker = InvokerHelper.instance

??? ??invoker.metaRegistry.setMetaClass(Foo.class,myMetaClass)

?

?

注册完了,我们就可以使用了:

?

??? ? def foo = new Foo()

??? ?

??? ? println foo.test()

???

?

一切都很简单,需要注意的是,在注册的时候,需要引入如下的类:

?

import org.codehaus.groovy.runtime.InvokerHelper

?

?

最后,我们运行上面的测试代码,得到如下的结果:

test

(编辑:李大同)

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

    推荐文章
      热点阅读