掘金 后端 ( ) • 2024-04-01 15:47

highlight: a11y-dark

1. 基础介绍

构建过程中的各个环节:清理、编译、测试、报告、打包、安装、部署。

构建(build),是面向过程的(从开始到结尾的多个步骤),涉及到多个环节的协同工作。构建过程的几个主要环节:

  • 清理:删除以前的编译结果,为重新编译做好准备。
  • 编译:将 Java 源程序编译为字节码文件。
  • 测试:针对项目中的关键点进行测试,确保项目在迭代开发过程中关键点的正确性。
  • 报告:在每一次测试后以标准的格式记录和展示测试结果。
  • 打包:将一个包含诸多文件的工程封装为一个压缩文件用于安装或部署。Java 工程对应 jar 包,Web 工程对应 war 包。
  • 安装:在 Maven 环境下特指将打包的结果 jar 包或 war 包安装到本地仓库中。
  • 部署:将打包的结果部署到远程仓库或将 war 包部署到服务器上运行。

Maven 的九个核心概念:POM、约定的目录结构、坐标、依赖管理、仓库管理、生命周期、插件和目标、继承、聚合。

Maven 中约定的目录结构:

Hello
|---src
|---|---main
|---|---|---java
|---|---|---resources
|---|---test
|---|---|---java
|---|---|---resources
|---pom.xml

说明:

Hello:根目录,也就是工程名。
|---src:源代码。
|---|---main:主程序。
|---|---|---java:主程序的 java 源码。
|---|---|---resources:主程序的配置文件。
|---|---test:测试程序。
|---|---|---java:测试程序的 java 源码。
|---|---|---resources:测试程序的配置文件。
|---pom.xml:Maven 工程的核心配置文件。

一般情况下,我们习惯上采取的措施是:约定>配置>编码。Maven 的 pom.xml 记录的关于构建项目的各个方面的设置,Maven 从 pom.xml 文件开始,按照约定的工程目录编译,测试,打包,部署,发布项目。

2. pom 标签

pom.xml即 Project Object Model 项目对象模型。Maven 把一个项目的结构和内容抽象成一个模型,在 xml 文件中进行声明,以方便进行构建和描述,pom.xml 是 Maven 的灵魂。所以,Maven 环境搭建好之后,所有的学习和操作都是关于 pom.xml 的。

2.1. modelVersion

Maven 模型的版本,对于 Maven2 和 Maven3 来说,它只能是 4.0.0。

<modelVersion>4.0.0</modelVersion>

2.2. groupId,artifactId,version

groupId 、artifactId 、version 三个元素生成了一个 Maven 项目的基本坐标,在众多的 Maven 项目中可以唯一定位到某一个项目,坐标也决定着将来项目在仓库中的路径及名称。

groupId

组织 id,一般是公司域名的倒写。格式可以为:

  1. 域名倒写。 例如 com.baidu。
  2. 域名倒写 + 项目名。例如 com.baidu.appollo。
<groupId>com.demo</groupId>

artifactId

项目名称,也是模块名称,对应 groupId 中项目中的子项目。

<artifactId>demo-web</artifactId>

version

项目的版本号。如果项目还在开发中,是不稳定版本,通常在版本后带-SNAPSHOT。version 使用三位数字标识,例如 1.1.0。

<version>0.0.1-SNAPSHOT</version>

2.3. packaging

项目打包的类型,可以是 jar、war、rar、ear、pom,不写的话默认是 jar。

<packaging>war</packaging>

2.4. dependencies,dependency

Maven 的一个重要作用就是管理 jar 包,为了一个项目可以构建或运行,项目中不可避免的,会依赖很多其他的 jar 包,在 Maven 中,这些 jar 就被称为依赖,使用标签dependency来配置。而这种依赖的配置正是通过坐标来定位的,由此我们也不难看出,Maven 把所有的 jar 包也都视为项目存在了。

<dependencies>
    <dependency>
        <groupId>org.springframework.boot</groupId>
        <artifactId>spring-boot-starter-web</artifactId>
    </dependency>

    <dependency>
        <groupId>org.springframework.boot</groupId>
        <artifactId>spring-boot-starter-test</artifactId>
        <scope>test</scope>
    </dependency>
</dependencies>

2.5. properties

properties 是用来定义一些配置属性的,例如project.build.sourceEncoding(项目构建源码编码方式),可以设置为 UTF-8,防止中文乱码。也可自定义一些相关依赖的版本号,便于日后统一升级。

<properties>
    <project.build.sourceEncoding>UTF-8</project.build.sourceEncoding>
    <java.version>1.8</java.version>
    <spring.boot.version>2.3.12.RELEASE</spring.boot.version>
</properties>

2.6. build

build 表示与构建相关的配置,例如设置编译插件。

<build>
    <plugins>
        <plugin>
            <groupId>org.springframework.boot</groupId>
            <artifactId>spring-boot-maven-plugin</artifactId>
            <version>${spring.boot.version}</version>
        </plugin>
    </plugins>
</build>

2.7. parent

在 Maven 中,如果多个模块都需要声明相同的配置,例如:groupId、version、有相同的依赖、或者相同的组件配置等,也有类似 Java 的继承机制,用 parent 声明要继承的父工程的 pom 配置。

<parent>
    <groupId>org.springframework.boot</groupId>
    <artifactId>spring-boot-starter-parent</artifactId>
    <version>2.5.3</version>
    <relativePath/> <!-- lookup parent from repository -->
</parent>

2.8. modules

在 Maven 的多模块开发中,为了统一构建整个项目的所有模块,可以提供一个额外的模块,该模块打包方式为 pom,并且在其中使用 modules 聚合的其它模块,这样通过本模块就可以一键自动识别模块间的依赖关系来构建所有模块,叫 Maven 的聚合。

<groupId>com.demo</groupId>
<artifactId>demo-web</artifactId>
<version>0.0.1-SNAPSHOT</version>
<modules>
    <module>web-common</module>
    <module>web-backstage</module>
    <module>web-forward</module>
    <module>web-special</module>
</modules>

<packaging>pom</packaging>

3. 命令介绍

Maven 提供一个项目构建的模型,把编译、测试、打包、部署等都对应成一个个的生命周期阶段,并对每一个阶段提供相应的命令,程序员只需要掌握一小堆命令,就可以完成项目的构建过程。

注意:执行命令必须在命令行进入 pom.xml 所在目录!

命令 描述 mvn clean 清理:会删除原来编译和测试的目录,即 target 目录,但是已经 install 到仓库里的包不会删除。 mvn compile 编译主程序:会在当前目录下生成一个 target,里边存放编译主程序之后生成的字节码文件。 mvn test-compile 编译测试程序:会在当前目录下生成一个 target,里边存放编译测试程序之后生成的字节码文件。 mvn test 测试:执行测试代码,会在 target 下生成一个目录 surefire-reports,保存测试结果文件。 mvn package 打包主程序:会编译、编译测试、测试、并且按照 pom.xml 配置把主程序打包生成 jar 包或者 war 包。 mvn install 安装主程序:会把本工程打包,并且按照本工程的坐标保存到本地仓库中。 mvn deploy 部署主程序:会把本工程打包,按照本工程的坐标保存到本地库中,并且还会保存到私服仓库中。还会自动把项目部署到 web 容器中。

4. 插件配置

Maven 默认会集成多种插件,这里只配置需要指定某些参数的插件,其他插件都是默认配置参数。(这里的配置仅仅是配置插件参数的意思,并不是启用某个插件的意思)。

<!--配置 maven 构建项目的参数-->
<build>
    <!--配置插件-->
    <plugins>
        <!--具体插件,有好多种,这里演示的编译插件的参数配置-->
        <plugin>
            <groupId>org.apache.maven.plugins</groupId>
            <!--插件名称-->
            <artifactId>maven-compiler-plugin</artifactId>
            <!--插件版本-->
            <version>3.8.1</version>
            <!--插件配置信息-->
            <configuration>
                <!--编译环境 JDK 版本-->
                <source>1.8</source>
                <!--运行环境 JDK 版本-->
                <target>1.8</target>
            </configuration>
        </plugin>
    </plugins>
</build>

5. 资源打包

src/main/java 和 src/test/java 这两个目录中的所有*.java文件会分别在 compile 和 test-comiple 阶段被编译,编译结果分别放到了 target/classes 和 targe/test-classes 目录中,但是这两个目录中的其他文件都会被忽略掉,如果需要把 src 目录下的文件包放到 target/classes 目录,作为输出的 jar 一部分。需要指定资源文件位置。

<build>
    <resources>
        <!-- 将src/main/java下的properties和xml资源编译到classes下 -->
        <resource>
            <!--资源文件所在目录-->
            <directory>src/main/java</directory>
            <!--包括目录下的.properties和.xml文件都会扫描到-->
            <includes>
                <include>**/*.properties</include>
                <include>**/*.xml</include>
            </includes>
            <!--filtering选项false,不启用过滤器,*.property已经起到过滤的作用了-->
            <filtering>false</filtering>
        </resource>
    </resources>
</build>

6. 依赖范围

范围 compile provided runtime test system 编译 是 是 否 否 是 测试 是 是 是 是 是 运行 是 否 是 否 否

compile:为默认的依赖有效范围。如果在定义依赖关系的时候,没有明确指定依赖有效范围的话,则默认采用该依赖有效范围。此种依赖,在编译、测试、运行时均有效。

provided:在编译、测试时有效,但是在运行时无效。例如:servlet-api,运行项目时,容器已经提供,就不需要 Maven 重复地引入一遍了。

runtime:在测试、运行时有效,但是在编译代码时无效。例如:JDBC 驱动实现,项目代码编译只需要 JDK 提供的 JDBC 接口,只有在测试或运行项目时才需要实现上述接口的具体 JDBC 驱动。另外 runntime 的依赖通常和 optional 搭配使用,optional 为 true。我可以用 A 实现,也可以用 B 实现。

test:只在测试时有效,例如:JUnit。

system:在编译、测试时有效,但是在运行时无效。和 provided 的区别是,使用 system 范围的依赖时必须通过 systemPath 元素显式地指定依赖文件的路径。由于此类依赖不是通过 Maven 仓库解析的,而且往往与本机系统绑定,可能造成构建的不可移植,因此应该谨慎使用。systemPath 元素可以引用环境变量。例如:

<dependency>
    <groupId>javax.sql</groupId>
    <artifactId>jdbc-stdext</artifactId>
    <version>2.0</version>
    <scope>system</scope>
    <systemPath>${java.home}/lib/rt.jar</systemPath>
</dependency>

scope 的依赖传递:

A–>B–>C。当前项目为A,A依赖于B,B依赖于C。知道B在A项目中的 scope,那么怎么知道C在A中的scope呢? 答案是: 当C是 test 或者 provided 时,C直接被丢弃,A不依赖C; 否则A依赖C,C的 scope 继承于B的 scope。

7. IDEA 模板

在 IDEA 中可以使用模板创建项目:

  • maven-archetype-quickstart:创建普通 Java 项目。
  • maven-archetype-webapp:创建 Web 项目。

8. 清理 Maven 仓库

Windows 系统下清理 Maven 仓库下载失败包的脚本:

@echo off
rem 这里写你的仓库路径
set REPOSITORY_PATH=C:\Users\wangbo\.m2\repository
rem 正在搜索...
for /f "delims=" %%i in ('dir /b /s "%REPOSITORY_PATH%\*lastUpdated*"') do (
    del /s /q %%i
)
rem 搜索完毕
pause
  • @echo off:关闭批处理中的命令回显。把 @ 加在 echo off 前面,表示也不显示 echo off 命令本身。
  • rem:注释命令,一般用来给程序加上注解,该命令后的内容不被执行,但能回显。
  • pause:暂停命令。

该脚本需要以管理员身份运行:

删除文件 - C:\Users\wangbo\.m2\repository\com\gtcom\gtcom-algorithmcenter\1.0\gtcom-algorithmcenter-1.0.pom.lastUpdated
删除文件 - C:\Users\wangbo\.m2\repository\com\gtcom\gtcom-sensitiveword\1.0.1\gtcom-sensitiveword-1.0.1.jar.lastUpdated
删除文件 - C:\Users\wangbo\.m2\repository\com\gtcom\gtcom-sensitiveword\1.0.1\gtcom-sensitiveword-1.0.1.pom.lastUpdated
删除文件 - C:\Users\wangbo\.m2\repository\org\glassfish\javax.el\3.0.1-b06-SNAPSHOT\javax.el-3.0.1-b06-SNAPSHOT.pom.lastUpdated
删除文件 - C:\Users\wangbo\.m2\repository\org\glassfish\javax.el\3.0.1-b07-SNAPSHOT\javax.el-3.0.1-b07-SNAPSHOT.pom.lastUpdated
删除文件 - C:\Users\wangbo\.m2\repository\org\glassfish\javax.el\3.0.1-b08-SNAPSHOT\javax.el-3.0.1-b08-SNAPSHOT.pom.lastUpdated
删除文件 - C:\Users\wangbo\.m2\repository\org\glassfish\javax.el\3.0.1-b11-SNAPSHOT\javax.el-3.0.1-b11-SNAPSHOT.pom.lastUpdated
请按任意键继续. . .