Gradle User Guide经常提到Gradle是声明性并使用按惯例构建。这是什么意思?
据我理解,这意味着,例如,在 java 插件中有类似的约定
来源必须位于src/main/java
,测试必须位于src/main/test
,src/main/resources
中的资源,build/libs
中的准备工具等等。但是,Gradle并不强制您使用这些约定,如果需要,您可以更改它们。
但是对于第二个概念,我对理解有更大的问题。和SQL一样,你说你想对你的查询做什么,但没有说数据库系统将如何获取它们,使用哪种算法来提取数据等。
请告诉我更多正确理解这些概念。感谢。
答案 0 :(得分:12)
您对按惯例构建的理解是正确的,因此我不必在那里添加任何内容。 (另见杰夫的回答。)
声明背后的想法是,您不必在任务级别上工作,自己实现/声明/配置所有任务及其依赖项,但可以在更高,更具说明性的级别上工作。您只需说“这是一个Java项目”(apply plugin: "java"
),“这是我的二进制存储库”(repositories { ... }
),“这里是我的来源”(sourceSets { ... }
),“这些是我的依赖“(dependencies { ... }
)。根据这个声明性信息,Gradle将确定需要哪些任务,它们的依赖关系以及如何配置它们。
答案 1 :(得分:11)
为了理解declarative编程风格,将它与imperative programming风格进行比较和对比是有用的。
声明性编程允许我们指定我们想要完成的。
在命令式编程中,我们指定 我们如何完成某些事情。
因此,当我们使用gradle时,正如Peter所描述的那样,我们创建声明,声明诸如“这是一个Java项目”或“这是一个Java Web应用程序”
然后,Gradle使用插件来提供处理诸如“Java Projects”或“Web Applications”之类的东西的构建服务。这很好,因为它是Gradle插件,其中包含与编译java类和构建war文件等任务有关的实现细节。将此对比另一个构建系统Make,这在本质上更为迫切。让我们看一下来自here:
的简单制作规则 foo.o : foo.c defs.h
cc -c -g foo.c
所以在这里,我们看到一条规则描述了如何从C源文件和C头文件构建对象文件foo.o。
Make规则有两个作用。
第一行说foo.o文件依赖于foo.c和foo.h.这行是一种声明,因为Make知道如何检查文件foo.o上的时间戳,看它是否比文件foo.c和foo.h更旧。如果foo.o较旧,则Make将调用下一行后面的命令。
下一行是势在必行的。
当foo.o文件比文件foo.c或foo.h中的任何一个文件旧时,第二行指定要运行的命令(cc - 一个C编译器)。另请注意,编写Makefile规则的人必须知道传递给cc命令的标志。
答案 2 :(得分:7)
按惯例构建的想法是,如果遵循默认约定,那么构建将更加简单。因此,当可以更改源目录时,您无需显式指定源目录。 Gradle带有逻辑默认值。这也称为约定优于配置。
根据彼得的回答编辑本部分以更清楚地说明陈述性质:
构建是声明性的想法是,您不需要指定需要完成的每个步骤。你没有说“做第1步,做第2步等”。您可以定义需要应用的插件(或任务),然后使用gradle构建任务执行图并确定执行内容的顺序。