我们知道,除了使用hook来拦截方法以外,我们还可以通过各种方式来实现方法。如,我们可以在类里直接实现方法;我们可以通过ExpandoMetaClass在运行期内添加方法;我们还可以通过ExpandoMetaClass在运行期内单独给一个对象添加方法。
所有的这些直接添加方法的途径,如果存在hook的话,都是要被hook拦截的。所以,我们可以说,系统是优先调用hook的。
而hook的调用顺序,我们在上一篇《Groovy探索之MOP 十一 运行期内覆盖invokeMethod》已经谈到过了。
本篇要谈到,却是除了hook方法以外的方法实现途径的调用顺序的问题。
我们都知道,如果有如下的一个类:
class Foo {
def getFoo()
{
'foo'
}
}
那么,我们可以通过如下的方法来调用它的方法:
def foo = new Foo()
println foo.foo
运行结果为:
foo
这就是我们的Gpath。
当然,我们也可以通过ExpandoMetaClass在运行期内添加这个"get"方法,如下:
Foo.metaClass.getFoo = {
->
'meta'
}
如果我们再做下面的测试:
def foo = new Foo()
println foo.foo
那么,运行结果为:
meta
从结果可以看出,在运行期内通过ExpandoMetaClass添加的方法是会覆盖类本身的方法的。
我们知道,在运行期内给类添加方法还有一种方式,即:
def mc = new ExpandoMetaClass(Foo.class,true)
mc.getFoo = {
->
'far'
}
mc.initialize()
下面,我将对上面的Foo类,在运行期内同时实行上面的两种方法的添加方式,然后在做测试,看看结果将会如何?
代码如下:
Foo.metaClass.getFoo = {
->
'meta'
}
def mc = new ExpandoMetaClass(Foo.class,true)
mc.getFoo = {
->
'far'
}
mc.initialize()
def foo = new Foo()
println foo.foo
}
运行结果为:
far