gradle构建多模块项目_Gradle入门:创建多项目构建

gradle构建多模块项目

尽管我们可以仅使用一个模块来创建一个运行中的应用程序,但有时将我们的应用程序划分为多个较小的模块是比较明智​​的。

因为这是一个相当普遍的用例,所以每个自重的构建工具都必须支持它,Gradle也不例外。 如果Gradle项目具有多个模块,则称为多项目构建。

这篇博客文章描述了如何使用Gradle创建多项目构建。

让我们开始看看Gradle构建的需求。

补充阅读:

如果您不熟悉Gradle, 则应先阅读以下博客文章,然后再继续阅读此博客文章:

  • Gradle入门:简介可帮助您安装Gradle,描述Gradle构建的基本概念,并描述如何使用Gradle插件向构建中添加功能。
  • Gradle入门:我们的第一个Java项目描述了如何使用Gradle创建Java项目并将应用程序打包到可执行jar文件中。
  • Gradle入门:依赖性管理介绍了如何管理Gradle项目的依赖性。

我们的Gradle构建要求

我们的示例应用程序具有两个模块:

  • 核心模块包含我们应用程序的其他模块所使用的通用组件。 在我们的例子中,它仅包含一个类: MessageService类返回字符串“ Hello World!”。 该模块只有一个依赖性:它具有一个使用Junit 4.11的单元测试。
  • app模块包含HelloWorld类,该类启动我们的应用程序,从MessageService对象获取消息,并将接收到的消息写入日志文件。 该模块具有两个依赖性:它需要核心模块,并使用Log4j 1.2.17作为日志记录库。

我们的Gradle版本还具有其他两个要求:

  • 我们必须能够使用Gradle运行我们的应用程序。
  • 我们必须能够创建不使用所谓的“胖罐”方法的可运行二进制分发。

如果您不知道如何使用Gradle运行应用程序并创建可运行的二进制发行版,
您应先阅读以下博客文章,然后再继续阅读此博客文章:

  • Gradle入门:创建二进制分发

让我们继续前进,了解如何创建满足我们要求的多项目构建。

创建多项目构建

我们的下一步是创建一个包含两个子项目的多项目Gradle构建: appcore 。 让我们从创建Gradle构建的目录结构开始。

创建目录结构

因为核心应用程序模块使用Java,所以它们都使用Java项目的默认项目布局 。 我们可以按照以下步骤创建正确的目录结构:

  1. 创建核心模块( core )的根目录,并创建以下子目录:
    • src / main / java目录包含核心模块的源代码。
    • src / test / java目录包含核心模块的单元测试。
  2. 创建应用程序模块( app )的根目录,并创建以下子目录:
    • src / main / java目录包含应用程序模块的源代码。
    • src / main / resources目录包含应用程序模块的资源。

现在,我们已经创建了所需的目录。 下一步是配置Gradle构建。 让我们从配置多项目构建中包含的项目开始。

配置我们的多项目构建中包含的项目

通过执行以下步骤,我们可以配置包含在多项目构建中的项目:

  1. settings.gradle文件创建到根项目的根目录。 多项目Gradle构建必须具有此文件,因为它指定了多项目构建中包含的项目。
  2. 确保应用程序核心项目包含在我们的多项目版本中。

我们的settings.gradle文件如下所示:

include 'app'
include 'core'

补充阅读:

  • Gradle用户指南:56.2设置文件
  • Gradle DSL参考:设置

让我们继续并配置核心项目。

配置核心项目

我们可以按照以下步骤配置核心项目:

  1. build.gradle文件创建到核心项目的根目录。
  2. 通过应用Java插件来创建Java项目。
  3. 确保核心项目从中央Maven2存储库获取其依赖项。
  4. 声明JUnit依赖关系(版本4.11)并使用testCompile配置。 此配置描述了核心项目在可以对其单元测试进行编译之前需要JUnit库。

核心项目的build.gradle文件如下所示:

apply plugin: 'java'repositories {mavenCentral()
}dependencies {testCompile 'junit:junit:4.11'
}

补充阅读:

  • Gradle入门:我们的第一个Java项目
  • Gradle入门:依赖管理

让我们继续并配置应用程序项目。

配置应用程序项目

在配置应用程序项目之前,我们必须快速浏览属于同一多项目构建的此类依赖项的依赖项管理。 这些依赖关系称为项目依赖关系。

如果我们的多项目构建具有项目A和B,并且项目B的编译需要项目A,则可以通过将以下依赖项声明添加到项目B的build.gradle文件中来配置此依赖项:

dependencies {compile project(':A')
}

补充阅读:

  • Gradle用户指南:51.4.3。 项目依赖
  • Gradle用户指南:57.7。 项目库依赖项

现在,我们可以按照以下步骤配置应用程序项目:

  1. build.gradle文件创建到应用程序项目的根目录。
  2. 通过应用Java插件来创建Java项目。
  3. 确保应用程序项目从中央Maven2存储库获取其依赖项。
  4. 配置所需的依赖项。 该应用程序项目在编译时具有两个依赖项:
    • Log4j(版本1.2.17)
    • 核心模块
  5. 创建一个可运行的二进制发行版 。

应用程序项目的build.gradle文件如下所示:

apply plugin: 'application'
apply plugin: 'java'repositories {mavenCentral()
}dependencies {compile 'log4j:log4j:1.2.17'compile project(':core')
}mainClassName = 'net.petrikainulainen.gradle.client.HelloWorld'task copyLicense {outputs.file new File("$buildDir/LICENSE")doLast {copy {from "LICENSE"into "$buildDir"}}
}applicationDistribution.from(copyLicense) {into ""
}

补充阅读:

  • Gradle入门:创建二进制分发

让我们继续并删除从核心应用程序项目的构建脚本中找到的重复配置。

删除重复的配置

当我们配置多项目构建的子项目时,我们向核心应用项目的构建脚本添加了重复的配置:

  • 因为两个项目都是Java项目,所以它们都应用Java插件。
  • 这两个项目都使用中央Maven 2存储库。

换句话说,两个构建脚本都包含以下配置:

apply plugin: 'java'repositories {mavenCentral()
}

让我们将此配置移到我们的根项目的build.gradle文件中。 在执行此操作之前,我们必须学习如何在根项目的build.gradle文件中配置子项目。

如果要将配置添加到名为core的单个子项目中,则必须将以下代码段添加到根项目的build.gradle文件中:

project(':core') {//Add core specific configuration here
}

换句话说,如果要将重复的配置移到根项目的构建脚本中,则必须将以下配置添加到其build.gradle文件中:

project(':app') {apply plugin: 'java'repositories {mavenCentral()}
}project(':core') {apply plugin: 'java'repositories {mavenCentral()}
}

这并没有真正改变我们的处境。 我们的构建脚本中仍然有重复的配置。 唯一的区别是,现在可以从根项目的build.gradle文件中找到重复的配置。 让我们消除这种重复的配置。

如果要将通用配置添加到根项目的子项目中,则必须将以下代码段添加到根项目的build.gradle文件中:

subprojects {//Add common configuration here
}

从根项目的build.gradle文件中删除重复的配置后,其外观如下:

subprojects {apply plugin: 'java'repositories {mavenCentral()}
}

如果我们拥有多项目构建中所有项目共享的配置,则应将以下代码段添加到
我们的根项目的build.gradle文件:

allprojects {//Add configuration here
}

补充阅读:

  • Gradle用户指南:57.1跨项目配置
  • Gradle用户指南:57.2子项目配置

现在,我们可以从子项目的构建脚本中删除重复的配置。 我们的子项目的新构建脚本如下所示:

core / build.gradle文件如下所示:

dependencies {testCompile 'junit:junit:4.11'
}

app / build.gradle文件如下所示:

apply plugin: 'application'dependencies {compile 'log4j:log4j:1.2.17'compile project(':core')
}mainClassName = 'net.petrikainulainen.gradle.client.HelloWorld'task copyLicense {outputs.file new File("$buildDir/LICENSE")doLast {copy {from "LICENSE"into "$buildDir"}}
}applicationDistribution.from(copyLicense) {into ""
}

现在,我们已经创建了一个多项目Gradle构建。 让我们找出我们刚刚做了什么。

我们只是做什么?

当我们在多项目构建的根目录中运行命令gradle projects时,我们看到以下输出:

> gradle projects
:projects------------------------------------------------------------
Root project
------------------------------------------------------------Root project 'multi-project-build'
+--- Project ':app'
\--- Project ':core'To see a list of the tasks of a project, run gradle <project-path>:tasks
For example, try running gradle :app:tasksBUILD SUCCESSFUL

如我们所见,此命令列出了根项目的子项目( appcore )。 这意味着我们刚刚创建了一个具有两个子项目的多项目Gradle构建。

当在多项目构建的根目录中运行命令gradle任务时,我们看到以下输出(下面仅显示了相关部分):

> gradle tasks
:tasks------------------------------------------------------------
All tasks runnable from root project
------------------------------------------------------------Application tasks
-----------------
distTar - Bundles the project as a JVM application with libs and OS specific scripts.
distZip - Bundles the project as a JVM application with libs and OS specific scripts.
installApp -Installs the project as a JVM application along with libs and OS specific scripts
run - Runs this project as a JVM application

如我们所见,我们可以使用Gradle运行应用程序,并创建一个不使用所谓的“胖罐”方法的二进制发行版。 这意味着我们已经满足了Gradle构建的所有要求。

附加信息:

  • Gradle用户指南:11.6。 获取有关构建的信息

让我们继续前进,找出从这篇博客文章中学到的知识。

摘要

这篇博客文章教会了我们三件事:

  • 多项目构建必须在根项目的根目录中具有settings.gradle文件,因为它指定了多项目构建中包含的项目。
  • 如果必须在多项目构建的所有项目中添加通用配置或行为,则应将此配置(使用allprojects )添加到根项目的build.gradle文件中。
  • 如果必须在根项目的子项目中添加通用配置或行为,则应将此配置(使用subprojects )添加到根项目的build.gradle文件中。

PS:您可以从Github获得此博客文章的示例应用程序 。

翻译自: https://www.javacodegeeks.com/2015/01/getting-started-with-gradle-creating-a-multi-project-build.html

gradle构建多模块项目

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.mzph.cn/news/338771.shtml

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈email:809451989@qq.com,一经查实,立即删除!

相关文章

python第一条入门程序_Python语言函数代码的执行流程

https://www.xin3721.com/eschool/pythonxin3721/Python语言函数代码的执行流程&#xff0c;为了保证函数的定义先于其首次调用时执行&#xff0c;我们需要知道中语句的执行顺序。执行总是从程序的第一行代码开始的&#xff0c;从上到下&#xff0c;从左到右&#xff0c;按顺序…

嵌入式C中,全局变量滥用的后果竟如此严重?

说起全局变量&#xff0c;就不得不提到“全局变量&#xff0c;局部变量&#xff0c;静态全局变量&#xff0c;静态局部变量”&#xff0c;这些都是编程语言中的基本概念。变量分为局部与全局&#xff0c;局部变量又可称之为内部变量。由某对象或某个函数所创建的变量通常都是局…

php登陆页面修改密码的功能,使用bootstrap创建登录注册页面并实现表单验证功能...

本篇文章给大家介绍一下使用bootstrap创建登录注册页面并实现单验证功能的方法。有一定的参考价值&#xff0c;有需要的朋友可以参考一下&#xff0c;希望对大家有所帮助。用bootstrap做登入注册页面&#xff0c;使用validate做表单验证技术&#xff1a;bootstrap&#xff0c;f…

java压缩文件读取_用Java读取/写入压缩和非压缩文件

java压缩文件读取这篇文章的主要原因是尝试不要重复自己&#xff08; DRY &#xff09;&#xff0c;因为通常&#xff0c;我会遇到递归的需求&#xff0c;即读写压缩的和非压缩的文件&#xff08;主要是JSON和CSV&#xff09;。 首先让我们看看如何读取文本文件。 注意我正在使…

vue router 参数_Vue.js项目开发技术解析

Vue.js项目开发技术解析一、Vue.js实例在一个Vue.js工程中&#xff0c;用于显示内容最基层的实例称之为根实例。通过该实例可以进行页面或组件的更新和显示。对于项目本身而言&#xff0c;无论是什么样的页面&#xff0c;都要基于该根实例进行显示。1.1、何为构造器对于Vue.js项…

deepin nginx连接php,利用docker运行nginx加上本机的php-fpm。访问html文件正常,但是访问php文件就报错404...

最近在虚拟机弄了一个deepin系统。打算使用docker加载nginx/1.17.6加在官方下载的PHP7.4.1(这个是本地编译的)。出现了以下的问题&#xff1a;1)访问html文件正常&#xff0c;但是访问php文件报404。根据网上的文章尝试&#xff1a;1)php运行不成功。在PHP的cli模式下是正常的。…

C语言中面向对象编程

C语言中面相对象的编程面向对象的重要思想就是数据隐藏&#xff0c;在面向对象语言中&#xff0c;对象可以包含私有变量。这样我们可以说他们具有内部状态,这些内部状态对其他对象是透明的。全局变量可以通过设置变量作用域来模拟私有变量&#xff08;甚至友元对象&#xff09;…

jmeter测试客户端_如何在JMeter中执行客户端Web性能测试?

jmeter测试客户端在本文中&#xff0c;我们将看到如何使用Jmeter插件进行客户端性能测试。 我将使用jmeter webdriver插件。 在开始本主题之前&#xff0c;请阅读我以前的文章中有关客户端性能测试的一些基本信息。 因此&#xff0c;让我们开始吧&#xff1a; 安装 通过这篇文…

java编译程序的基本命令是什么,【填空题】Java中编译java 程序的命令是 1 ,执行java程序的命令是 java 。...

【填空题】Java中编译java 程序的命令是 1 ,执行java程序的命令是 java 。更多相关问题[多选] 下列骨折中属于关节外骨折的是()。[多选] 骨折早期局部的并发症包括()。[多选] 典型中1/3段锁骨骨折的内侧端移位方向是()。[多选] 骨关节结核的诊断要点包括()。[多选] 骨痂形成的方…

python range 小数_python中如何表示一个无限循环小数?(不用分数的形式)python,使用range语...

python中如何表示一个无限循环小数&#xff1f;(不用分数的形式) python,使用range语www.zhiqu.org 时间&#xff1a; 2020-12-07只能用分数或者你自己设计一个对象&#xff0c;保留指定长度的有效位range()只能产生int无法产生float但是可以曲线救国for i in range(0,10,1…

C语言实现面向接口编程

面向接口编程话不多说&#xff0c;先上一个面向接口编程的Demo:参考demo&#xff1a;1#include 2#include 34/********************************************5 * Note: 共用接口的定义 6 * author:bug菌 7 *******************************************/8struct Interface {9 …

java ee用户登录_EE Servlet 3:使用会话和过滤器开发用户登录

java ee用户登录我在上一篇文章中介绍了Application类&#xff0c;您可以在其中设置后端服务。 我添加的一个示例服务是UserService 。 该服务将加载包含用户名和密码集的Java用户属性文件&#xff1b; 稍后将用于对用户进行身份验证以登录到Web应用程序。 现在&#xff0c;我将…

php 静态方法 call,php的 __callStatic 函数

现在很多框架中调用方法都是Foo::bar()这种格式的,但是他们真的是静态方法吗?这种情况在 larave 中尤其常见,但是开发过程中很明显这些有一部分不是静态的,比如你使用一个模型User,那么你每次实例化出来他都是一个全新的,互不影响,这里就用到了一个魔术方法__callStatic举个栗…

python高手之路第三版_《Python高手之路(第3版)》——1.3 版本编号-阿里云开发者社区...

本节书摘来自异步社区《Python高手之路(第3版)》一书中的第1章&#xff0c;第1.3节&#xff0c;作者&#xff3b;法&#xff3d;Julien Danjou&#xff0c;王飞龙 译&#xff0c;更多章节内容可以访问云栖社区“异步社区”公众号查看。1.3 版本编号可能你已经有所了解&#xf…

「C语言」指针数组 数组指针 指针函数 函数指针

相信很多人和我一样&#xff0c;有着这样的恐惧&#xff0c;那就是这四个玩意怎么也分不清&#xff0c;这都是啥啥啥啥呢&#xff1f;今天我们来具体分析一下。其实要具体了解这四个概念&#xff0c;只需要了解符号优先级&#xff0c;并关注最后两字&#xff0c;你就成功了一半…

spring 组件扫描_避免不必要的Spring配置组件扫描

spring 组件扫描我在堆栈溢出中遇到了一个有趣的问题。 Brett Ryan有问题&#xff0c;Spring Security配置被初始化了两次。 当我查看他的代码时&#xff0c;我发现了问题所在。 让我展示显示代码。 他有相当标准的Spring应用程序&#xff08;不使用Spring Boot&#xff09;。…

php滚动到指定位置,JQuery插件:ScrollTo平滑滚动到页面指定位置

ScrollTo是一款基于jQuery的滚动插件&#xff0c;当点击页面的链接时&#xff0c;可以平滑地滚动到页面指定的位置。适用在一些页面内容比较多&#xff0c;页面长度有好几屏的场合&#xff0c;本文以DEMO为示例讲解该插件的应用。查看演示DEMO使用方法1&#xff0d;准备jQuery库…

聚集索引和非聚集索引的区别_武汉无疫情小区居民可在小区内非聚集性个人活动...

3月18日&#xff0c;武汉市新冠肺炎疫情防控指挥部社区疫情防控组发布《关于无疫情小区、村(队)调整管控措施的意见》(下简称《意见》)指出&#xff0c;全市认定的无疫情小区、村(队)可对管控措施作有序调整。 被认定为无疫情小区的&#xff0c;允许居民分批、分时段、分楼栋&a…

C语言 | 指向指针的指针排序

C语言实现用指向指针的指针的方法对5个字符串排序并输出。 解题思路&#xff1a;读者看着道题的时候&#xff0c;首先要知道什么时指针&#xff0c;指向指针的指针应该怎么用&#xff0c;一般在开发中不这样用&#xff0c;读者要看明白&#xff0c;这个很锻炼思维的。C语言源代…

jooq sql_使用jOOQ和JavaFX将SQL数据转换为图表

jooq sql最近&#xff0c;我们已经展示了Java 8和函数式编程将如何为使用jOOQ和Java 8 lambda和Streams进行SQL数据的函数数据转换为Java开发人员带来新的视角。 今天&#xff0c;我们将这一步骤更进一步&#xff0c;将数据转换为JavaFX XYChart.Series以根据数据生成美观的条形…