1. Maven
1.1. Maven是什么
Maven 是 Apache 软件基金会组织维护的一款专门为 Java 项目提供构建和依赖管理支持的工具。
一个 Maven 工程有约定的目录结构,约定的目录结构对于 Maven 实现自动化构建而言是必不可少的一环,就拿自动编译来说,Maven 必须 能找到 Java 源文件,下一步才能编译,而编译之后也必须有一个准确的位置保持编译得到的字节码文件。
我们在开发中如果需要让第三方工具或框架知道我们自己创建的资源在哪,那么基本上就是两种方式:
- 通过配置的形式明确告诉它
- 基于第三方工具或框架的约定 Maven 对工程目录结构的要求
1.2. Maven依赖
Maven 中最关键的部分,我们使用 Maven 最主要的就是使用它的依赖管理功能。当 A jar 包用到了 B jar 包中的某些类时,A 就对 B 产生了依赖,那么我们就可以说 A 依赖 B。
依赖管理中要解决的具体问题:
- jar 包的下载:使用 Maven 之后,jar 包会从规范的远程仓库下载到本地
- jar 包之间的依赖:通过依赖的传递性自动完成
- jar 包之间的冲突:通过对依赖的配置进行调整,让某些 jar 包不会被导入
1.3. 依赖范围
maven的依赖范围包括: compile,provide,runtime,test,system。
- compile:表示编译范围,指 A 在编译时依赖 B,该范围为默认依赖范围。编译范围的依赖会用在编译,测试,运行,由于运行时需要,所以编译范围的依赖会被打包。
- provided:provied 依赖只有当 jdk 或者一个容器已提供该依赖之后才使用。provide 依赖在编译和测试时需要,在运行时不需要。例如:servlet api被Tomcat容器提供了。
- runtime:runtime 依赖在运行和测试系统时需要,但在编译时不需要。例如:jdbc 的驱动包。由于运行时需要,所以 runtime 范围的依赖会被打包。
- test:test 范围依赖在编译和运行时都不需要,只在测试编译和测试运行时需要。例如:Junit。由于运行时不需要,所以 test 范围依赖不会被打包。
- system:system 范围依赖与 provide 类似,但是必须显示的提供一个对于本地系统中 jar 文件的路径。一般不推荐使用。
编译时不需要。例如:jdbc 的驱动包。由
于运行时需要,所以 runtime 范围的依赖会被打包。
test:test 范围依赖在编译和运行时都不需要,只在测试编译和测试运行时需要。例如:Junit。由
于运行时不需要,所以 test 范围依赖不会被打包。
system:system 范围依赖与 provide 类似,但是必须显示的提供一个对于本地系统中 jar 文件的
路径。一般不推荐使用。
1.4. 依赖的传递
- A 依赖 B,B 依赖 C,那么在 A 没有配置对 C 的依赖的情况下,A 里面能不能直接使用 C?
Maven的依赖传递是指,当项目A依赖项目B,而项目B又依赖项目C时,Maven会自动将项目C的依赖传递给项目A,不需要在项目A的pom.xml中显式声明对C的依赖。 - 再以上的前提下,C 是否能够传递到 A,取决于 B 依赖 C 时使用的依赖范围。
B 依赖 C 时使用 compile 范围:可以传递
B 依赖 C 时使用 test 或 provided 范围:不能传递,所以需要这样的 jar 包时,就必须在需要的地方明确配置依赖才可以。
1.5. 依赖的排除
当 A 依赖 B,B 依赖 C 而且 C 可以传递到 A 的时候,A 不想要 C,需要在 A 里面把 C 排除掉。而往往这种情况都是为了避免 jar 包之间的冲突。
所以配置依赖的排除其实就是阻止某些 jar 包的传递。因为这样的 jar 包传递过来会和其他 jar 包冲突。
一般通过使用excludes标签配置依赖的排除:
2. Gradle
2.1. Gradle是什么
Gradle是继Maven之后的新一代构建工具,它采用基于groovy的DSL语言作为脚本,相比传统构建工具,通过XML来配置而言,最直观上的感受就是脚本更加的简洁、优雅。如果你之前对Maven有所了解,那
么可以很轻易的转换到Gradle,它采用了同Maven一致的目录结构,可以与Maven一样使用Maven中央仓库以及各类仓库的资源,并且Gradle默认也内置了脚本转换命令可以方便的将POM转换为gradle.build。
2.1.1. 标准结构
Gradle遵循COC(convention over configuration约定优于配置)的理念,默认情况下提供了与maven相同的项目结构配置
大体结构如下:
project root
src/main/java(测试)
src/main/resources
src/test/java(测试源码目录)
src/test/resources(测试资源目录)
src/main/webapp(web工程)
在一些老项目上,可能目录结构并不是标准结构,然而一般开发人员又不好进行结构调整.此时可以通过配置sourceSet来指定目录结构
sourceSets {
main {
java {
srcDir 'src/java'
}
resources {
srcDir 'src/resources'
}
}
}
2.2. Gradle脚本
一个简单的Gralde脚本,或许包含如下内容,其中标明可选的都是可以删掉的部分
- 插件引入:声明你所需的插件
- 属性定义(可选):定义扩展属性
- 局部变量(可选):定义局部变量
- 属性修改(可选):指定project自带属性
- 仓库定义:指明要从哪个仓库下载jar包
- 依赖声明:声明项目中需要哪些依赖
- 自定义任务(可选):自定义一些任务
//定义扩展属性(给脚本用的脚本)
buildScript {
repositories {
mavenCentral()
}
}
//应用插件,这里引入了Gradle的Java插件,此插件提供了Java构建和测试所需的一切。
apply plugin: 'java'
//定义扩展属性(可选)
ext {
foo="foo"
}
//定义局部变量(可选)
def bar="bar"
//修改项目属性(可选)
group 'pkaq'
version '1.0-SNAPSHOT'
//定义仓库,当然gradle也可以使用各maven库 ivy库 私服 本地文件等,后续章节会详细介绍(可选)
repositories {
mavenLocal()
maven {
url 'https://maven.aliyun.com/repository/public/'
}
mavenCentral()
}
//定义依赖,这里采用了g:a:v简写方式,加号代表了最新版本(可选)
dependencies {
compile "cn.pkaq:ptj.tiger:+"
}
//自定义任务(可选)
task printFoobar {
println "${foo}__${bar}"
}
2.3. Gradle依赖管理
通常而言,依赖管理包括两部分,对依赖的管理以及发布物的管理;依赖是指构建项目所需的构件(jar包等)。例如,对于一个应用了spring普通的java web项目而言,spring相关jar包即项目所需的依赖。发布物,则是指项目产出的需要上传的项目产物。
2.3.1. 采用变量统一控制版本号
dependencies {
def bootVersion = "1.3.5.RELEASE"
compile "org.springframework.boot:spring-boot-starter-
web:${bootVersion}",
"org.springframework.boot:spring-boot-starter-data-
jpa:${bootVersion}",
"org.springframework.boot:spring-boot-starter-
tomcat:${bootVersion}"
}
2.3.2. 自动获取最新版本依赖
如果你想某个库每次构建时都检查是否有新版本,那么可以采用+来让Gradle在每次构建时都检查并应用最新版本的依赖。当然也可以采用1.x,2.x的方式来获取某个大版本下的最新版本。
dependencies {
compile "org.springframework.boot:spring-boot-starter-web:+"
}
2.4. Gradle坐标
仓库中构件(jar包)的坐标是由configurationName "group:name:version:classifier@extension"组成的字符串构成,如同Maven中的GAV坐标,Gradle可借由此来定位你想搜寻的jar包。
在gradle中可以通过以下方式来声明依赖:
testCompile group: 'junit', name: 'junit', version: '4.0'
2.5. 外部依赖
可以通过如下方式声明外部依赖,Gradle支持通过map方式或者gv的简写方式传入依赖描述,这些声明依赖会去配置的repository查找。
dependencies {
// 采用map方式传入单个
compile group: 'commons-lang', name: 'commons-lang', version: '2.6'
// 采用map方式传入多个
compile(
[group: 'org.springframework', name: 'spring-core', version: '2.5'],
[group: 'org.springframework', name: 'spring-aop', version: '2.5']
)
// 采用简写方式声明
compile 'org.projectlombok:lombok:1.16.10'
// 采用简写方式传入多个
compile 'org.springframework:spring-core:2.5',
'org.springframework:spring-aop:2.5'
}
2.6. 项目依赖
此类依赖多见于多模块项目,书写方式如下,其中:是基于跟项目的相对路径描述
compile project(':project-foo')
3.问题聚合
3.1Maven的优点和缺点?
Maven是一个流行的Java项目管理和构建工具,它具有许多优点和缺点。以下是一些可能的优点和缺点:
优点:
- 标准化管理:Maven提供了一种标准化的项目管理和构建方式,使得项目更加易于管理和维护。它提供了一组共享的插件和约定,使项目构建过程更加一致和可靠。
- 依赖管理:Maven能够管理项目的依赖关系,包括自动下载和管理库和框架的依赖。这使得项目更加易于集成和测试,减少了手动配置和管理的需要。
- 自动化构建:Maven能够自动化构建项目,使得代码编译、测试、打包和部署等过程更加快速和可靠。这有助于减少错误和提高代码质量。
- 集成测试:Maven能够集成测试框架,如JUnit、TestNG等,使得测试更加容易和可靠。它还可以生成测试报告,以便于跟踪和解决测试中的问题。
- 文档生成:Maven能够生成项目的文档,包括JavaDoc、Scaladoc等,这有助于项目成员更好地理解和使用代码。
缺点: - 学习曲线陡峭:Maven使用了一种基于XML的配置文件来定义项目的构建过程,对于初学者来说可能比较困难。此外,Maven的插件系统和概念也比较多,需要花费一定时间来学习。
- 配置复杂:虽然Maven提供了许多预设的插件和约定,但项目的构建过程仍然需要进行大量的配置。这可能会导致配置错误或过度配置,影响项目的构建速度和稳定性。
- 灵活性不足:由于Maven使用了一种基于XML的配置文件来定义构建过程,因此对于一些特殊的构建需求可能难以满足。此外,Maven的插件系统也可能限制了某些项目的定制化需求。
3.2 Gradle的优点和缺点?
Gradle是一个灵活的、功能强大的自动化构建工具,用于管理项目的构建、报告和测试。以下是Gradle的一些优点和缺点:
优点:
- 声明式构建:Gradle采用声明式构建方式,使得构建脚本更加清晰、易读和维护。
- 强大的依赖管理:Gradle具有强大的依赖管理功能,能够自动下载和管理项目所需的依赖项,减少了手动配置的繁琐。
- 灵活性:Gradle具有高度的灵活性,允许开发者根据项目需求自定义构建过程,例如添加插件、配置任务等。
- 跨平台兼容性:Gradle可以在不同的操作系统和环境中运行,具有较好的跨平台兼容性。
- 丰富的插件生态系统:Gradle拥有庞大的插件生态系统,可以支持各种开发语言和工具。
缺点: - 学习曲线:相较于一些传统的构建工具(如Apache Ant、Apache Maven),Gradle的使用需要一定的学习成本。虽然它的语法相对简单,但对于初学者来说,理解其构建逻辑和概念可能需要一些时间。
- 配置繁琐:虽然Gradle提供了丰富的配置选项和功能,但过度配置可能会使构建脚本变得复杂且难以维护。
- 兼容性问题:尽管Gradle具有良好的跨平台兼容性,但在某些情况下,特定平台的特性可能无法得到完全支持。
- 社区支持:虽然Gradle的插件生态系统相对丰富,但对于一些非主流语言或工具的支持可能不够完善。
总体而言,Gradle是一个强大且灵活的构建工具,适用于各种规模的项目。在选择使用Gradle时,需要考虑学习曲线、配置复杂性以及社区支持等因素。
3.3 Maven的坐标概念是什么?
在Maven中,坐标是一个重要的概念,用于唯一标识一个项目或依赖。Maven坐标主要由三个部分组成:groupId、artifactId和version。
groupId:通常表示项目所属的组织或公司,它以反向域名的方式开头,用于在Maven中唯一标识一个组织。例如,org.apac是Apache Software Foundation的groupId。
artifactId:是项目的名称,通常与源代码库的名称相一致。在定义项目坐标时,artifactId是必需的。
version:表示项目的版本号。每个项目可以有多个版本,通过不同的version号进行区分。在定义依赖关系时,通常需要指定依赖的version号。
除了groupId、artifactId和version,Maven坐标还可以包括其他一些元素,如packaging、scope等,用于更详细地描述项目或依赖的属性。
总之,Maven坐标通过唯一的标识符,将项目和依赖进行组织和管理,方便构建、发布和分享。
3.4 为什么选择Maven构建项目?
选择Maven构建项目的原因有很多,以下是一些主要的理由:
- 简化构建过程:Maven简化了开发人员的工作,屏蔽了很多细节,使得开发人员可以专注于业务逻辑,而不是底层细节。
- 统一管理依赖:Maven能够快速实现依赖的配置,从远程仓库中自动下载对应的依赖,管理依赖版本和解决依赖冲突,减少了手动管理的繁琐。
- 提供丰富的插件支持:Maven拥有庞大的插件生态系统,支持各种开发语言和工具,使得项目构建更加方便和快速。
- 自动化构建和测试:Maven能够自动化编译、测试、打包和部署项目,提高了构建的可靠性和效率。
- 标准化项目管理:Maven提供了一套标准的项目结构和构建流程,使得项目更加易于维护和管理。
- 跨平台兼容性:Maven可以在不同的操作系统和环境中运行,具有较好的跨平台兼容性。
- 丰富的项目信息管理:Maven提供了大量的项目信息,包括POM文件中的版本号、插件、依赖等,这些信息有助于项目成员更好地理解和使用代码。
- 最佳实践指南:Maven会汇总当前最佳开发实践的原则,并通过Maven影响其他项目。
- 透明化更新:Maven为Maven客户端提供了一种安装更新的简单方法,开发人员可以简单便捷的利用Maven的最新特性。
综上所述,选择Maven构建项目可以带来许多好处,包括简化构建过程、统一管理依赖、自动化构建和测试、标准化项目管理等。因此,Maven成为了一个流行的Java项目管理和构建工具。
3.5 为什么选择Gradle构建项目?
选择Gradle构建项目的原因有很多,以下是一些主要的理由:
- 先进的构建系统:Gradle是一个先进的构建系统,具有灵活性和可扩展性,支持自动化构建和测试,使得构建过程更加可靠和高效。
- 基于DSL的配置语言:Gradle使用一种基于Groovy的领域特定语言(DSL)来描述和处理构建逻辑,使得构建脚本更加清晰、易读和维护。
- 强大的依赖管理:Gradle能够自动下载和管理项目的依赖项,减少了手动配置的繁琐,提高了构建的一致性和可靠性。
- 灵活的插件机制:Gradle支持插件机制,开发者可以根据项目需求自定义构建过程,支持各种开发语言和工具,提高了构建的灵活性和扩展性。
- 跨平台兼容性:Gradle可以在不同的操作系统和环境中运行,具有较好的跨平台兼容性,使得项目在不同的平台上能够得到一致的构建结果。
- 社区支持:Gradle拥有庞大的社区支持,有大量的插件和资源可供参考和使用,可以帮助开发者快速解决问题和实现项目需求。
- 易于集成其他工具和框架:Gradle可以轻松地与其他工具和框架集成,例如CI/CD流水线、版本控制系统等,提高了项目管理和协作的效率。
- 强大的测试支持:Gradle对测试提供了强大的支持,包括单元测试、集成测试和端到端测试等,可以帮助开发者确保代码的质量和可靠性。
- 可定制的构建生命周期:Gradle允许开发者自定义构建生命周期的阶段和任务,以满足项目的特殊需求。
- 强大的性能优化能力:Gradle提供了性能优化相关的功能和插件,可以帮助开发者提高应用程序的性能和响应能力。
综上所述,选择Gradle构建项目可以带来许多好处,包括先进的构建系统、基于DSL的配置语言、强大的依赖管理、灵活的插件机制、跨平台兼容性等。因此,Gradle成为了一个流行的自动化构建工具。
**粗体** _斜体_ [链接](http://example.com) `代码` - 列表 > 引用
。你还可以使用@
来通知其他用户。