Groovy和DSL二: Closure Delegate

Groovy和DSL一: 模拟Gradle中,我们搭建了一个DSL脚本的解析框架。现在我们来专注于Closuer的实现,主要的方法是通过Closure Delegate

Delegate

在Project.groovy中,closure是没有实现的:

    void dependencies(Closure cl){
        println "dependencies get called"
    }

由纯groovy调用构成的closure很好处理,直接调用call函数,比如:

def cl={
    println "hello"
    println "world"
}

cl.call()

但如果closure中包含自定义的函数,那就不行了,比如我们的dependencies中,包含着testImplementation和implementation两个函数,直接运行closure.run是无法识别的

dependencies {
    // Use JUnit test framework.
    testImplementation 'junit:junit:4.13.2'

    // This dependency is used by the application.
    implementation 'com.google.guava:guava:30.1.1-jre'
}

这时候就要用我们的Delegate了,基本的处理范式是这样的:

  • 创建一个类,实现closure中的自定义的函数
  • 设置closure的delegate到该类
  • 运行closure,当遇到自定义关键字时,会映射到delegate类中

示例如下:

def cl = {
    println "hello"
    println "world"

    //foo是自定义函数
    foo "hello closuer"
}

//使用delegate处理自定义函数
class ClDelegate{
    void foo(String param){
        println param
    }
}

ClDelegate clDlg = new ClDelegate()
cl.delegate = clDlg
cl.resolveStrategy = Closure.DELEGATE_ONLY
cl.call()

Bradle实现

明白了套路之后,回头看看我们的bradle配置文件:

repositories {
    // Use Maven Central for resolving dependencies.
    mavenCentral()
}

dependencies {
    // Use JUnit test framework.
    testImplementation 'junit:junit:4.13.2'

    // This dependency is used by the application.
    implementation 'com.google.guava:guava:30.1.1-jre'
}

tasks.register("t1"){
    println "task t1 executed"
}

tasks.register("t2"){
    doLast{
        println "task t2 executed"
    }
}

要实现的Delegate如下:

  • repositories delegate,实现其中的mavenCentral函数
  • dependencies delegate,实现其中的testImplementation和implementation函数
  • task delegate,实现doLast函数

最终的代码如下:

package groovydls
import java.util.concurrent.ConcurrentHashMap
import java.util.concurrent.ConcurrentMap

abstract class Project extends Script{
    TaskContainer tasks

    Project(){
        tasks = new TaskContainer()
    }

    void repositories(Closure cl){
       RepositoriesDelegate repDlg = new RepositoriesDelegate()
       cl.delegate = repDlg
       cl.resolveStrategy = Closure.DELEGATE_ONLY
       cl.call()
    }

    void dependencies(Closure cl){
       DependenciesDelegate depDlg = new DependenciesDelegate()
       cl.delegate = depDlg
       cl.resolveStrategy = Closure.DELEGATE_ONLY
       cl.call()
    }
}

class TaskContainer{
   static final ConcurrentMap<String, Closure> taskMap = [:] as ConcurrentHashMap
   void register(String name, Closure cl){
        taskMap."$name" = cl
   }

   void run(String name){
        Closure cl = taskMap."$name"
        TaskDelegate tDlg = new TaskDelegate()
        cl.delegate = tDlg
        cl.resolveStrategy = Closure.DELEGATE_ONLY
        cl.call()
   }
}


class RepositoriesDelegate{
    void mavenCentral(){
        println "mavenCentral get called"
    }
}

class DependenciesDelegate{
    void implementation(String id){
        println "implementation get called, id:"+id
    }

    void testImplementation(String id){
        println "testImplementation get called, id:"+id
    }
}

class TaskDelegate{
    void doLast(Closure cl){
        cl.call()
    }
}

小结

至此,一个bradle就完成了,在bradle.build中添加更多的task,寻找些乐子吧。

整体项目代码在:

Ref



《 “Groovy和DSL二: Closure Delegate” 》 有 4 条评论

  1. I never made it to work that day where can i buy cheap cytotec price Lukassen HGM, Schönbeck Y, Adang EMM, Braat DDM, Zielhuis GA, Kremer JAM

  2. Other suitable PPIs or histamine 2 antagonists may be therapeutic alternatives that can be used to avoid adverse consequences can i purchase generic cytotec for sale

  3. It won t be long before elevated systolic blood pressure you join the rest of the kings, Create a spiritual connection how to take priligy

  4. This study adds knowledge to the existing evidence of the associations between cardiac drug therapy and anxiety priligy review members

回复 can i order cheap cytotec 取消回复

您的邮箱地址不会被公开。 必填项已用 * 标注

About Me

一位程序员,会弹吉他,喜欢读诗。
有一颗感恩的心,一位美丽的妻子,两个可爱的女儿
mail: geraldlee0825@gmail.com
github: https://github.com/lisuxiaoqi
medium: https://medium.com/@geraldlee0825