1 项目目录下执行 ./gradlew build,用.gradlew自动构建
首先有一个gradlew(linux)或者gradlew.bat(win)是用来检查java配置,环境配置之类的东西
然后去启动gradle/wrapper/gradle-wrapper.jar去检测本地gradle版本是否和配置文件gradle/wrapper/gradle-wrapper.properties中的一样,不一样则下载指定版本。
然后获取到gradle后,会根据build.gradle(类似maven的pom.xml配置库的文件)里的东西加载库。
我们的gradlew脚本去构建的指定版本的gradle
gradle/wrapper/gradle-wrapper.properties中的
distributionUrl=https\://mirrors.huaweicloud.com/gradle/gradle-6.9.1-bin.zip
以下是这个gradlew.bat脚本的主要功能和流程:
-
设置环境:脚本首先尝试确定
APP_HOME
目录,这个目录是脚本所在的路径。 -
检查 Java 环境:脚本会检查
JAVA_HOME
环境变量,如果没有设置,会尝试使用系统默认的java
命令。如果找不到 Java,脚本会终止并提示错误。 -
设置 JVM 参数:脚本可以接受一些 JVM 参数,例如内存设置 (
-Xmx64m
,-Xms64m
)。这些参数可以通过DEFAULT_JVM_OPTS
、JAVA_OPTS
和GRADLE_OPTS
变量来配置。 -
处理文件描述符:在某些系统上,脚本会尝试增加最大文件描述符的数量,以提高系统的性能。
-
OS 特定处理:脚本会根据不同的操作系统做一些特定处理。例如,针对 macOS,脚本会设置应用程序的名称和图标。
-
启动 Gradle:最终,脚本会执行
java
命令,运行org.gradle.wrapper.GradleWrapperMain
类,这个类是 Gradle Wrapper 的核心,它会下载并启动指定版本的 Gradle,并根据项目的build.gradle
文件执行构建任务。
总结来说,当你运行 ./gradlew
时,这个脚本会确保你的系统上有合适的 Java 环境,配置必要的参数,并启动 Gradle 构建工具来执行你在项目中定义的任务。
Gradle Wrapper 是什么?
Gradle Wrapper 是 Gradle 提供的一种机制,允许项目团队在不同的开发环境中使用一致的 Gradle 版本。它包含几个文件:
gradlew
和gradlew.bat
:用于在类 Unix 系统和 Windows 上启动 Gradle 的脚本文件。gradle/wrapper/gradle-wrapper.jar
:包含 Gradle Wrapper 的 Java 类,用于下载并启动指定版本的 Gradle。gradle/wrapper/gradle-wrapper.properties
:配置文件,用于指定要使用的 Gradle 版本和下载地址。
使用 gradlew
的意义
-
一致性:通过
gradlew
,项目确保所有开发者使用相同版本的 Gradle,而不依赖于系统上已经安装的 Gradle。这避免了由于 Gradle 版本不一致导致的构建问题。 -
简便性:新加入项目的开发者不需要手动安装 Gradle,只需要运行
./gradlew build
,Gradle Wrapper 会自动下载并使用正确版本的 Gradle。 -
自动化:在 CI/CD 环境中,通过
gradlew
,可以保证构建环境始终使用项目指定的 Gradle 版本,而不需要对构建环境进行额外配置。
Gradle Wrapper (gradlew
) 启动流程
Gradle Wrapper (gradlew
和 gradlew.bat
) 是一个工具,确保你使用的 Gradle 版本与项目定义的一致。以下是 gradlew
启动的主要流程:
-
执行
gradlew
脚本:- 当你运行
./gradlew
命令时,操作系统会调用gradlew
脚本文件(在类 Unix 系统中是一个 Shell 脚本,在 Windows 中是一个批处理文件gradlew.bat
)(我们两个都有)。
- 当你运行
-
设置环境:
- 脚本会解析和设置运行 Gradle 所需的环境,包括确定脚本的位置,设置 JVM 参数,处理系统特定的配置(如路径转换)。
-
检查和下载 Gradle:
- 脚本会检查本地(business-directory/gradle/wrapper下)是否已经存在
gradle-wrapper.jar
(用来下载和加载指定版本gradle的包)和指定版本的 Gradle。如果不存在,它会下载指定版本的 Gradle 分发包(由gradle-wrapper.properties
(配置文件,配置需要的版本和配置)文件中的distributionUrl
定义)。
- 脚本会检查本地(business-directory/gradle/wrapper下)是否已经存在
-
运行 Gradle:
- 下载完成后,脚本会运行
gradle-wrapper.jar
,该文件启动指定版本的 Gradle 并执行实际的构建任务。
- 下载完成后,脚本会运行
-
执行构建任务:
- Gradle 启动后,它会根据
build.gradle
文件中的定义来执行构建任务,如编译代码、运行测试、打包等。
- Gradle 启动后,它会根据
2.gradle和maven
与 Maven 的不同
Gradle 和 Maven 是两个不同的构建工具,它们在设计理念、功能和使用方式上有一些主要区别:
-
构建脚本语言:
- Gradle:使用 Groovy 或 Kotlin DSL 编写构建脚本(
build.gradle
或build.gradle.kts
)。这种方式更加灵活和可编程。(有点类似于java类里定义属性那个样子) - Maven:使用 XML 编写构建配置(
pom.xml
)。XML 格式结构化清晰,但不如编程语言灵活。(尖括号一层层包裹,类似html5那种,可读性不好)这个 build.gradle 文件配置了一个复杂的项目构建过程,包括: 应用插件。 配置了运行时和测试时的依赖。 排除和强制使用特定版本的依赖。 定义了源集和编译任务的依赖。 配置了编译器的选项。 plugins { id 'java' 插件用于扩展 Gradle 的功能,通常包含了构建、编译、测试等方面的配置。 } group = 'com.example' version = '1.0.0' repositories { mavenCentral() } dependencies { implementation 'org.springframework.boot:spring-boot-starter' 项目要用的依赖,三方库和其他子项目的功能 testImplementation 'junit:junit:4.13.2' 做测试框架的依赖比如junit,mockito,testng } tasks.register('customTask') { doLast { println 'This is a custom task.' } } //配置排除路径,防止冲突 configurations { implementation.exclude module: "infra-auth-hub-public-javaclient" implementation.exclude module: "infra-audit-trail-public-javaclient" } //确保使用指定版本的库 configurations.all { resolutionStrategy { force 'com.google.guava:guava:32.0.1-jre' } }
- Gradle:使用 Groovy 或 Kotlin DSL 编写构建脚本(
-
<project> <dependencies> <dependency> <groupId>com.example</groupId> <artifactId>example-lib</artifactId> <version>1.0.0</version> </dependency> </dependencies> <build> <plugins> <plugin> <groupId>org.apache.maven.plugins</groupId> <artifactId>maven-compiler-plugin</artifactId> <version>3.8.1</version> <configuration> <source>1.8</source> <target>1.8</target> </configuration> </plugin> </plugins> </build> </project>
构建逻辑:
- Maven: 使用生命周期(如
compile
,test
,package
等)来定义构建过程,生命周期是预定义的,步骤之间的顺序由 Maven 确定。Maven 构建生命周期 | 菜鸟教程 (runoob.com) - Gradle: 使用任务(tasks)和任务依赖(task dependencies)来定义构建过程,任务可以自定义,并且可以按需执行,构建过程更具灵活性。
- Maven: 使用生命周期(如
-
配置方式:
- Maven: 配置是静态的,所有的依赖和插件都在
pom.xml
文件中定义。 - Gradle: 允许动态配置和编程式配置,可以在构建脚本中编写逻辑来处理复杂的构建需求。
- Maven: 配置是静态的,所有的依赖和插件都在
-
构建缓存和增量构建:
- Maven: 没有内置的增量构建支持,通常需要重新构建所有内容。
- Gradle: 提供了增量构建和构建缓存,能够更智能地决定哪些部分需要重新构建,从而提高构建效率。
5.maven要指定artifactId项目号,gradle不需要,它通过分组和版本来标识。
6.gradle有tasks,maven没有
-
Maven: Maven 的核心概念是“生命周期”(Lifecycle),包括
compile
、test
、package
等阶段。每个阶段会执行一组预定义的插件任务。这些生命周期和阶段使得 Maven 的构建过程更加固定和线性。Maven 主要通过插件来执行具体的任务,插件的配置在pom.xml
中进行。 -
Gradle: Gradle 提供了更加灵活的任务系统。你可以定义任意数量的任务,并且可以控制任务的执行顺序和条件。Gradle 使用
tasks
来定义和管理这些任务。例如: -
tasks.register('hello') { doLast { println 'Hello, world!' } }
在这个示例中,
hello
是一个自定义任务,它在构建过程中可以被执行。Gradle 的任务系统允许你创建复杂的任务依赖和执行逻辑,这使得 Gradle 在处理复杂构建过程时更为灵活。
3.常用属性
在 Maven 和 Gradle 中,有一些常用的属性和配置选项,用于定义和管理构建过程。以下是一些常见的属性及其意义:
Maven 常用属性
-
groupId
- 意义: 定义项目的组 ID,通常是组织或公司的唯一标识符。
- 示例:
<groupId>com.example</groupId>
-
artifactId
- 意义: 定义项目的唯一 ID,通常是项目的名称或模块的名称。
- 示例:
<artifactId>my-app</artifactId>
-
version
- 意义: 定义项目的版本号,用于标识不同版本的发布。
- 示例:
<version>1.0.0</version>
-
packaging
- 意义: 定义项目的打包方式,例如 JAR、WAR、POM 等。
- 示例:
<packaging>jar</packaging>
-
dependencies
- 意义: 定义项目所需的外部依赖,包括其坐标(
groupId
,artifactId
,version
)。
- 意义: 定义项目所需的外部依赖,包括其坐标(
<dependencies>
<dependency>
<groupId>org.springframework</groupId>
<artifactId>spring-core</artifactId>
<version>5.3.10</version>
</dependency>
</dependencies>
6repositories
- 意义: 定义项目的依赖库所在的仓库地址。
<repositories>
<repository>
<id>central</id>
<url>https://repo1.maven.org/maven2</url>
</repository>
</repositories>
7plugins
- 意义: 定义项目使用的插件及其配置,插件用于扩展构建功能。
<build>
<plugins>
<plugin>
<groupId>org.apache.maven.plugins</groupId>
<artifactId>maven-compiler-plugin</artifactId>
<version>3.8.1</version>
<configuration>
<source>1.8</source>
<target>1.8</target>
</configuration>
</plugin>
</plugins>
</build>
Gradle 常用属性
-
group
- 意义: 定义项目的组 ID,类似于 Maven 的
groupId
。 - 示例:
group = 'com.example'
- 意义: 定义项目的组 ID,类似于 Maven 的
-
version
- 意义: 定义项目的版本号,类似于 Maven 的
version
。 - 示例:
version = '1.0.0'
- 意义: 定义项目的版本号,类似于 Maven 的
-
sourceCompatibility
- 意义: 定义 Java 源代码的兼容版本。
- 示例:
sourceCompatibility = '1.8'
-
targetCompatibility
- 意义: 定义生成的字节码的兼容版本。
- 示例:
targetCompatibility = '1.8'
-
repositories
- 意义: 定义项目的依赖库所在的仓库地址。
repositories {
mavenCentral()
maven { url 'https://repo1.maven.org/maven2' }
}
在 Maven 和 Gradle 中,有一些常用的属性和配置选项,用于定义和管理构建过程。以下是一些常见的属性及其意义:
Maven 常用属性
-
groupId
- 意义: 定义项目的组 ID,通常是组织或公司的唯一标识符。
- 示例:
<groupId>com.example</groupId>
-
artifactId
- 意义: 定义项目的唯一 ID,通常是项目的名称或模块的名称。
- 示例:
<artifactId>my-app</artifactId>
-
version
- 意义: 定义项目的版本号,用于标识不同版本的发布。
- 示例:
<version>1.0.0</version>
-
packaging
- 意义: 定义项目的打包方式,例如 JAR、WAR、POM 等。
- 示例:
<packaging>jar</packaging>
-
dependencies
- 意义: 定义项目所需的外部依赖,包括其坐标(
groupId
,artifactId
,version
)。 - 示例: xml
复制代码
<dependencies> <dependency> <groupId>org.springframework</groupId> <artifactId>spring-core</artifactId> <version>5.3.10</version> </dependency> </dependencies>
- 意义: 定义项目所需的外部依赖,包括其坐标(
-
repositories
- 意义: 定义项目的依赖库所在的仓库地址。
- 示例: xml
复制代码
<repositories> <repository> <id>central</id> <url>https://repo1.maven.org/maven2</url> </repository> </repositories>
-
plugins
- 意义: 定义项目使用的插件及其配置,插件用于扩展构建功能。
- 示例: xml
复制代码
<build> <plugins> <plugin> <groupId>org.apache.maven.plugins</groupId> <artifactId>maven-compiler-plugin</artifactId> <version>3.8.1</version> <configuration> <source>1.8</source> <target>1.8</target> </configuration> </plugin> </plugins> </build>
Gradle 常用属性
-
group
- 意义: 定义项目的组 ID,类似于 Maven 的
groupId
。 - 示例:
group = 'com.example'
- 意义: 定义项目的组 ID,类似于 Maven 的
-
version
- 意义: 定义项目的版本号,类似于 Maven 的
version
。 - 示例:
version = '1.0.0'
- 意义: 定义项目的版本号,类似于 Maven 的
-
sourceCompatibility
- 意义: 定义 Java 源代码的兼容版本。
- 示例:
sourceCompatibility = '1.8'
-
targetCompatibility
- 意义: 定义生成的字节码的兼容版本。
- 示例:
targetCompatibility = '1.8'
-
repositories
- 意义: 定义项目的依赖库所在的仓库地址。
- 示例:
repositories { mavenCentral() maven { url 'https://repo1.maven.org/maven2' } }
-
dependencies
- 意义: 定义项目所需的外部依赖。
dependencies {
implementation 'org.springframework:spring-core:5.3.10'
}
’
7plugins
- 意义: 定义项目使用的插件及其配置,插件用于扩展构建功能。
plugins {
id 'java'
id 'application'
}
8tasks
- 意义: 定义和配置构建任务。
tasks.register('hello') {
doLast {
println 'Hello, world!'
}
}