Groovy探索之MOP 六 运行期内添加构造器和静态方法

构造器是我们喜欢重载的一个方法,因为我们在实例化一个类的时候,会遇到各种各样的情况,比如在某些情况下,一系列类的实例可能有一些相同值的属性,这时候,我们在实例化对象时,就不希望把这些相同的值分别注入到每一对象中,这样的工作很繁琐。

这时候,我们就会重载构造器,但一些时候,比如一些Bean对象,它们的属性很多,我们就不好在类中重载很多构造器。比如,我们有如下的一个GroovyBean类:

class Reader {
String province
String city
String name
int age

}

这是一个很简单的GroovyBean类,我们不会在里面重载构造器了。一般我们都会做如下的实例化:

def reader = new Reader(province:'Guangdong',city:'Shenzhen',name:'Tom',age:22)

现在,我们有这样一个场景:可能有一批的读者,都是来自广东省深圳市,那么我们把每一个读者都做上面的初始化,就显得太繁琐了。

这时候,我们就可以在运行期内给上面的GroovyBean类重载一个构造器了。如下所示:

Reader.metaClass.constructor = {String name,int age ->
new Reader(province:'Guangdong',city:'Shenzhen',name:name,age:age)
}

在这个构造器里,我们把属性"province"和"city"赋给默认值,然后再给构造器注入两个参数即可。测试代码如下:

def reader1 = new Reader('Tom',22)
println"""
name:    ${reader1.name}
age:     ${reader1.age}
address: ${reader1.province} ${reader1.city}"""
def reader2 = new Reader('Mike',20)
println """
name:    ${reader2.name}
age:     ${reader2.age}
address: ${reader2.province} ${reader2.city}"""

运行结果为:

name:    Tom
age:     22
address: Guangdong Shenzhen

name:    Mike
age:     20
address: Guangdong Shenzhen

在运行期内我们也可以给类添加一些静态方法,这里添加静态方法有两种方式,第一种是在运行期内进行拦截。比如我们有如下的一个类:

class Foo {
}

现在这个类里一个方法也没有,我们将要在运行期内给它添加一个静态方法,如下:

Foo.metaClass.'static'.invokeMethod = {
String name,args1 ->
def metaMethod = Foo.metaClass.getStaticMetaMethod(name,args1)
def result
if(metaMethod) result = metaMethod.invoke(name,args1)
else result = 'foo'
result
}

那么,我们就可以测试它了:

println Foo.foo()

运行结果为:

foo

时间: 2024-09-17 03:59:48

Groovy探索之MOP 六 运行期内添加构造器和静态方法的相关文章

Groovy探索之MOP 八 运行期内给类和对象添加属性或方法

我们都知道,在Groovy语言中,我们可以使用MOP特性在运行期内添加属性或方法. 这种添加包括两个层面的添加: 第一, 是给一个类添加属性或方法.也就是说,如果我们在运行期内给一个类添加了属性或方法,那么添加了以后,所有这个类实例化的对象,都将拥有了这个属性或方法. 第二, 第二,是给一个对象添加属性或方法.也就是说,如果我们在运行期内给一个对象添加了属性或方法,那么添加了以后,只有这个对象才拥有这个属性或方法.换句话说,如果我们再给这个对象的类实例化一个对象,那么该对象则不能拥有我们刚添加的

Groovy探索之MOP 十一 运行期内覆盖invokeMethod

我们很早就会使用Groovy语言的hook,即"invokeMethod"方法和其他的几个方法.我们会在一个类中实现"invokeMethod"方法,用来分派所有的或部分的在运行期内调用的该类实例的方法.这些我们在<Groovy探索之MOP 一 invokeMethod和methodMissing方法>已经详细的谈到过. 现在,我们已经深入的接触到了Groovy语言的MetaClass,更是也到处使用到了ExpandoMetaClass.我们都已经知道,

Groovy探索之MOP 七 运行期内的方法和属性分析

在Groovy语言里,运行期内的方法和属性分析有三种方式,它们分别是: 第一, 继承自Java语言的反射方式. 第二, 使用"respondsTo"和"hasProperty"方法. 第三, 使用"hasMetaMethod"和"hasMetaProperty"方法. 以上三种方法都能在运行期内分析某个方法或属性是否存在,相信我们看到这里,一定会想,它们之间是否有什么区别呢? 漫谈这三种运行期内的方法和属性分析方式以及它们之间

Groovy探索之MOP 十二 方法的调用顺序

我们知道,除了使用hook来拦截方法以外,我们还可以通过各种方式来实现方法.如,我们可以在类里直接实现方法:我们可以通过ExpandoMetaClass在运行期内添加方法:我们还可以通过ExpandoMetaClass在运行期内单独给一个对象添加方法. 所有的这些直接添加方法的途径,如果存在hook的话,都是要被hook拦截的.所以,我们可以说,系统是优先调用hook的. 而hook的调用顺序,我们在上一篇<Groovy探索之MOP 十一 运行期内覆盖invokeMethod>已经谈到过了.

Groovy探索之MOP 十五 方法名的动态性

到目前为止,我们的<Groovy探索之MOP>系列已经谈到了使用ExpandoMetaClass的方方面面,但值得注意的是,我们通过ExpandoMetaClass给一个类在运行期内添加一个方法,不管是普通方法还是静态方法,我们都是添加一个确定方法名的方法.即我们添加一个方法名为A的方法,然后才能使用这个方法A. 然而,方法名的动态性,其实是我们早已接触过的事情,比如在<Groovy探索之invokeMethod方法>里,我们就可以创建形如"sortByXxxxx()&q

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

既然Groovy语言是Java语言的扩展,那么我们在使用Groovy语言的时候,就很难与Java语言真正脱得了干系,那怕我们是在做一个纯Groovy语言的项目,如Grails项目.我们可能在Groovy代码中会用到遗留的Java类和包:也可能是为了性能的原因,我们不得不在Groovy语言中使用到Java类:等等. 如果我们要对于Java类使用Groovy语言的MOP,比如我们想给一个Java类的对象在运行期内添加一个方法.那么我们该怎么办呢? 比如,我们有如下的一个Java类: //(Java代

Groovy探索之MOP 四 使用ExpandoMetaClass来实现Mixin

国内很多的文章都在说Groovy语言的Mixin机制就是Groovy语言的Categories机制.其实,在外面的Blog上,大量有人在讨论Groovy语言应该如何实现它自己的Mixin机制,这就是说明Groovy语言的Mixin机制还没有定型,处在讨论之中.Categories机制当然也能实现部分的Mixin功能,就像Java语言的接口机制,还有组合等等,都能实现部分的Mixin功能.就像C++语言的多继承一样,这些"古老"的机制都能或多或少的实现部分的Mixin功能. 其实,Mix

Groovy探索之MOP 五 针对接口类型的动态性

这里所说的接口类型,在Java语言和Groovy语言中,当然是既包括了基类类型和接口.所谓"接口类型的动态性",指的是在运行期内给基类或接口动态的添加方法,使得基类以及它的子类.接口的实现,都能访问这些方法. 这个功能一向是我比较感兴趣的一个功能.因为我们在编程的实践中,会使用各种各样的应用API,还有JDK,在使用它们的过程中,可能有一些接口及它们的子类我们会经常使用到,但是在使用的过程中,我们又感到非常的不方便.这时候,我们可以使用Categories机制来对我们所使用的类进行扩充

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

其实,阻止拦截的使用像在<Groovy探索之MOP 十三 Interceptor 三(1)>中的最后一个例子那像的使用并不多,更多的是在使用拦截器的客户那里决定是否使用拦截器.还是上一篇的那个例子: class Hello { def hello(name) { "hello,$name" } } 我们现在明确的把类中所有的方法进行拦截,拦截器如下: class AllInterceptor implements Interceptor{ Object beforeInvo