网站卡密代理怎么做,wordpress增加浏览量,休闲小零食网站开发方案,青岛市南区城市建设局网站目录 【4】Gradle-快速入门使用【Gradle多模块项目详解】创建多项目构建添加子项目命名建议 项目依赖项项目路径不同模块的build.gradle配置 子项目之间共享构建逻辑公约插件跨项目配置buildSrc开发公约插件 调整多模块项目配置修改项目树的元素 了解Gralde配置时间和执行时间并… 目录 【4】Gradle-快速入门使用【Gradle多模块项目详解】创建多项目构建添加子项目命名建议 项目依赖项项目路径不同模块的build.gradle配置 子项目之间共享构建逻辑公约插件跨项目配置buildSrc开发公约插件 调整多模块项目配置修改项目树的元素 了解Gralde配置时间和执行时间并行项目执行解耦项目 个人主页: 【⭐️个人主页】 需要您的【 点赞关注】支持 【4】Gradle-快速入门使用【Gradle多模块项目详解】 本文核心知识点 多模块项目 多模块添加子项目 多模块全局配置方式 多模块间依赖 多模块项目调整 多模块buildSrc目录 多模块配置时间和执行时间 并行执行和解耦合
创建多项目构建
Gradle中的多项目构建由一个根项目和一个或多个子项目组成。
基本的多项目构建包含一个根项目和一个子项目。这是一个多项目构建的结构它包含一个名为app的子项目:
├── app
│ ...
│ └── build.gradle
└── settings.gradle这是启动任何Gradle项目的推荐项目结构。build init插件还会生成遵循这种结构的框架项目——一个根项目和一个子项目。
️ 注意:根项目没有Gradle构建文件build.gradle只有一个定义要包含的子项目的设置文件settings.gradle。 settings.gradle
rootProject.name basic-multiproject
include app在这种情况下Gradle将在app目录中查找构建文件。
我们可以通过运行gradlew projects命令来查看多项目构建的结构 使用 gradle -q run命令启动app项目
添加子项目
假设我们想要在前面创建的项目中添加另一个名为infrastructure的子项目。我们所需要做的就是在根设置文件中添加另一个include语句: settings.gradle
rootProject.name study-spring3
include app
// 基础设施模块
include infrastructure结构
.
├── app
│ ...
│ └── build.gradle
├── infrastructure
│ ...
│ └── build.gradle
└── settings.gradle命名建议
随着项目的发展命名和一致性变得越来越重要。为了保持构建的可维护性我们建议采用以下方法: 为子项目保留默认项目名称:可以在设置文件中配置自定义项目名称。但是对于开发人员来说跟踪哪个项目属于哪个文件夹是不必要的额外工作。 对所有项目名称使用kebab大小写格式: kebab大小写格式是指所有字母都是小写单词之间用破折号( - )字符分隔(例如kebab-case-formatting)。这已经是许多大型项目的实际模式。此外Gradle支持kebab case名称缩写。 在设置文件settings.gradle中定义根项目名称: rootProject.name 有效地为整个构建分配了一个名称这在构建扫描等报告中使用。如果没有设置根项目名称则名称将是容器目录名称这可能是不稳定的(即您可以将项目签出到任何目录)。如果没有设置根项目名并且它被检出到文件系统的根目录(例如/或C:)则该名称将随机生成。
项目依赖项
❓ 如果一个项目需要另一个项目在其编译类路径上生成的jar该怎么办? ❓ 如果它还需要其他项目的传递依赖项怎么办? 显然这是Java多项目构建中非常常见的用例。正如在项目依赖项中提到的Gradle为此提供了项目依赖项。
├── buildSrc
│ ...
├── api
│ ├── src
│ │ └──...
│ └── build.gradle
├── domain-core
│ ├── src
│ │ └──...
│ └── build.gradle
├── infrastructure
│ ├── src
│ │ └──...
│ └── build.gradle
└── settings.gradle有三个项目api, domain-core, infrastructure,它们之间的依赖关系是
我们使用:分隔符来定义项目路径。
项目路径 将给定的项目添加到构建中。所提供列表中的每个路径都被视为要添加到构建中的项目的路径。注意这些路径不是文件路径而是指定新项目在项目层次结构中的位置。因此所提供的路径必须使用:字符作为分隔符(而不是’/)。 所提供路径的最后一个元素用作项目名称。提供的路径被转换为相对于根项目目录的项目目录。项目目录可以在项目被包含之后通过改变’projectDir属性来改变(参见ProjectDescriptor.setProjectDir(java.io.File)) 使用项目路径的一些常见示例如下:
// include two projects, foo and foo:bar
// directories are inferred by replacing : with /
include foo:bar// include one project whose project dir does not match the logical project path
include baz
project(:baz).projectDir file(foo/baz)// include many projects whose project dirs do not match the logical project paths
file(subprojects).eachDir { dir -include dir.nameproject(:${dir.name}).projectDir dir
}不同模块的build.gradle配置
appdependencies {implementation org.apache.commons:commons-textimplementation project(:infrastructure)}infrastructure dependencies {implementation project(:domain-core)}domain-core 【无】
执行gradle app:dependencies查看app的依赖项
子项目之间共享构建逻辑
公约插件
通常多项目构建中的子项目具有一些共同的特征。 例如几个子项目可能包含特定编程语言的代码而另一个子项目可能专门用于文档。代码质量规则适用于所有代码子项目但不适用于文档子项目。与此同时具有共同特征的子项目可能服务于不同的目的——它们可能会产生不同的工件类型来进一步区分它们 例如 1. 公共库 : 发布到某些Mavne存储库的库 2. 内部库 :其他子项目在项目内部依赖的库 3. 命令行应用程序 : 具有特定打包要求的应用程序 4. Web服务 : 具有与上述不同的特定包装要求的应用程序 等等 其他一些代码子项目可能专门用于测试目的等。 以上特征标识了子项目的类型。或者换句话说子项目的类型告诉我们该项目具有哪些特征。 所以 多个特征组成了一类的子项目。一类子项目可以作为公共构建进行子项目间共享。
Gradle推荐的组织构建逻辑的方法是使用其插件系统。 插件应该定义子项目的类型。 事实上Gradle核心插件以相同的方式建模 例如Java插件配置了一个通用的java项目而Java库插件在内部应用Java插件并配置特定于Java库的方面。同样应用程序插件应用和配置Java插件和分发插件。 您可以通过应用和配置核心和外部插件来编写自定义构建逻辑并创建自定义插件定义新的项目类型并配置特定于您的项目或组织的约定特征。
跨项目配置
另一种令人沮丧的子项目之间共享构建逻辑的方法是通过 subprojects {} allprojects {} DSL结构进行跨项目配置。 通过交叉配置构建逻辑可以注入子项目在查看子项目的构建脚本时这并不明显这使得理解特定子项目的逻辑更加困难。从长远来看交叉配置通常会随着越来越多的条件逻辑和更高的维护负担而变得复杂。
交叉配置还可以引入项目之间的配置时间耦合这可能会阻止按需配置等优化正常工作。 配置时间耦合: 指下载插件和依赖的时间。指多项目构建时子项目间交叉依赖耦合在一起。
交叉配置有两种最常见的用途都可以使用约定插件的方式更好地建替代
将插件或其他配置应用于特定类型的子项目。 通常如果子项目是X类型那么交叉配置部分就可以完成然后配置y。这相当于将X-conventions插件直接应用于子项目。 从某种类型的子项目中提取信息。此用例可以使用传出的配置变体进行建模。
buildSrc开发公约插件
建议将约定插件的源代码和测试放在项目根目录的 buildSrc目录中。
使用约定插件编写构建逻辑的多项目构建的另一个更复杂和现实的例子是Gradle构建工具本身的构建。
目录buildSrc被视为包含的构建。发现目录后Gradle会自动编译和测试此代码并将其放入构建脚本的类路径中。对于多项目构建只能有一个buildSrc目录该目录必须位于根项目目录中。buildSrc应优于脚本插件因为它更容易维护、重构和测试代码。 buildSrc使用适用于Java和Groovy项目的相同源代码约定。它还提供了对Gradle API的直接访问。其他依赖项可以在buildSrc下的专用build.gradle中声明。
可以使用gradle init 生成buildSrc目录。并进行约定插件的gradle编写
调整多模块项目配置
多项目构建总是由具有单个根的树表示。树中的每个元素代表一个项目。项目有一个路径表示项目在多项目构建树中的位置。在大多数情况下项目路径与项目在文件系统中的物理位置一致。然而这种行为是可配置的。项目树在settings.gradle文件中创建。设置文件的位置也是根项目的位置。
在设置文件中您可以使用include方法构建项目树。 通过修改settings.gradle文件中的include子项目应用。可以调整子项目的相关信息
include project1, project2:child, project3:child1include方法将项目路径作为参数。项目路径假定等于相对的物理文件系统路径。 例如默认情况下路径“services:api”映射到文件夹“services/api”相对于项目根目录。你只需要指定树的叶子。这意味着包含“services:hotels:api”路径将导致创建3个项目“services”、“services:hotels”和“services:hotels:api”。 修改项目树的元素
rootProject.name main
include(project-a)
project(:project-a).projectDir file(../my-project-a)
project(:project-a).buildFileName project-a.gradle了解Gralde配置时间和执行时间
构建阶段描述了每个Gradle构建的阶段。让我们放大多项目构建的配置和执行阶段。 这里的配置意味着评估项目的构建脚本文件其中包括下载所有插件和构建脚本依赖项。 默认情况下所有项目的配置发生在执行任何任务之前。这意味着当请求来自单个项目的单个任务时首先配置多项目构建的所有项目。每个项目都需要配置的原因是Gradle项目模型的任何部分 访问和更改 的灵活性。
并行项目执行
并行执行试图
减少执行受IO绑定或以其他方式不会消耗所有可用CPU资源的多项目构建的总构建时间。为小型项目的执行提供更快的反馈而无需等待其他项目的完成。
并行项目执行允许并行执行解耦多项目构建中的独立项目另见解耦项目。虽然并行执行在配置时并不严格要求解耦但长期目标是提供一套强大的功能这些功能将可用于完全解耦的项目。这些功能包括
按需配置。并行配置项目。为不变的项目重复使用配置。项目级最新检查。在构建依赖项目的地方使用预先建造的工件。
并行执行是如何工作的 首先您需要告诉Gradle使用并行模式。您可以使用--parallel命令行参数或配置构建环境Gradle属性。除非您提供特定数量的并行线程否则Gradle会尝试根据可用的CPU内核选择正确的数量。每个并行工作线程在执行任务时都只拥有给定的项目。任务依赖性得到完全支持并行工作线程将首先开始执行上游任务。请记住在并行模式下不能保证解耦任务的字母顺序如在顺序执行过程中所示。换句话说在并行模式下任务一旦其依赖项完成任务工作线程可以运行它们任务将立即运行这可能比它们在顺序构建期间开始时更早。您应该确保正确声明任务依赖项和任务输入/输出以避免订购问题。 解耦项目
Gradle允许任何项目在配置和执行阶段访问任何其他项目。
如果两个项目不直接访问彼此的项目模型它们就会脱钩。解耦的项目只能在声明的依赖项方面进行交互项目依赖项和/或任务依赖项。任何其他形式的项目交互即通过修改另一个项目对象或从另一个项目对象读取值都会使项目耦合。在配置阶段耦合的后果是如果使用“按需配置”选项调用gradle构建的结果可能会在几个方面存在缺陷。执行阶段耦合的后果是如果使用并行选项调用gradle一个项目任务运行得太晚无法影响并行项目构建的任务。Gradle不会试图检测耦合并警告用户因为引入耦合的可能性太多。
项目耦合的一种非常常见的方法是使用配置注入。它可能不会立即显现出来但使用allprojects和subprojects关键字等关键Gradle功能会自动使您的项目耦合。这是因为这些关键字用于定义项目的 build.gradle文件中。通常这是一个“根项目”只不过定义了通用配置但就Gradle而言这个根项目仍然是一个成熟的项目通过使用allprojects该项目有效地与所有其他项目耦合。将根项目耦合到子项目不会影响按需配置但在任何子项目的build.gradle文件中使用allprojects和subprojects都会产生影响。
为了充分利用跨项目配置而不会出现并行和“按需配置”选项的问题请遵循以下建议
避免子项目的构建脚本引用其他子项目更喜欢从根项目进行交叉配置。避免在执行时更改其他项目的配置。