groovy不仅能方法注入,也可以方法合成,利用之前说的methodMissing方法。我们知道在找不到方法的时候会回调这个方法,然后我通过错误回调的时候进行方法注入。
方法合成
class Manager {
def methodMissing(String name, def args) {
println 'missing method'
if (name.startsWith('distribute')){
//生成的class文件 调用方式不一样
// println metaClass
Manager p = this
// println p.metaClass
def m=p.metaClass.invokeMethod(this,"respondsTo",name,args)
if(!m){
println "inject method"
p.metaClass."$name" = {
println "invoke $name"
}
}
"$name"(args)
}
return null
}
}
def p = new Manager()
//println p.metaClass
p.distribute()
p.distribute()
p.distribute()
结果
missing method
inject method
invoke distribute
invoke distribute
invoke distribute
方法委托
(一) 使用methodMissing进行注入。
class Work1{
def execute1(){
"execute1"
}
}
class Work2{
def execute2(){
"execute2"
}
}
class WorkManager{
Work1 work1 = new Work1()
Work2 work2 = new Work2()
def methodMissing(String name, def args) {
WorkManager wm = this
def response=null;
if (work1.respondsTo(name,args)){
wm.metaClass."$name" = {
response= work1.invokeMethod(name,it)
}
"$name"(args)
} else if(work2.respondsTo(name,args)){
wm.metaClass."$name" = {
response= work2.invokeMethod(name,it)
}
"$name"(args)
}
return response
}
}
def wm = new WorkManager()
assert wm.execute1()=='execute1'
assert wm.execute2()=='execute2'
在找不到方法的时候,判断代理对象是否具有方法并且动态注入方法进行委托。
(二)使用delegate委托
class Work1{
def execute1(){
"execute1"
}
}
class Work2{
def execute2(){
"execute2"
}
}
class WorkManager1{
{
delegate(Work1,Work2)
}
def delegate(Class... classes){
//创建对应的对象
def objects = classes.collect {it.newInstance()}
WorkManager1 wm = this
//注入methodMissing方法
wm.metaClass.methodMissing = {
String name, def args ->
//查找调用的方法的实现对象
def object = objects.find {it.respondsTo(name,args)}
if (object){
//动态注入方法
wm.metaClass."$name" = {
object.invokeMethod(name,it)
}
invokeMethod(name,args)
}
}
}
}
def wm1 = new WorkManager1()
assert wm.execute1()=='execute1'
assert wm.execute2()=='execute2'
(三) 使用@Delegate注解委托
class Work1{
def execute1(){
"execute1"
}
}
class Work2{
def execute2(){
"execute2"
}
}
class WorkManager2{
@Delegate Work1 work1 = new Work1()
@Delegate Work2 work2 = new Work2()
}
def manager2 = new WorkManager2()
assert manager2.execute1()=='execute1'
assert manager2.execute2()=='execute2'
groovy的语法虽然灵活,其实对于运行的代价是比java要高一些的,具体使用就看取舍了。