Groovy语法学习(九)MOP探索之方法合成与委托

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要高一些的,具体使用就看取舍了。

猜你喜欢

转载自blog.csdn.net/a568478312/article/details/79930896