Bootstrap

Maven 使用教程

Maven 是什么

Maven 是 Apache 软件基金会组织维护的一款专门为 Java 项目提供构建和依赖管理支持的工具。

什么是 Maven 的构建

Maven 的构建包括 clean(清除)、 compile(编译)、 test(测试)、 site(报告)、 package(打包)、 install(安装)、 deploy(部署),各自的具体作用如下:

  • clean(清除):清除上一次的构建信息,为下一次构建做准备,不执行该步骤也是可以的,会自动覆盖。
  • compile(编译):将 Java 源文件编译成字节码 Class 文件。
  • test(测试):运行提前准备好的测试程序,执行 test 目录下的测试用例。
  • site(报告):记录测试结果。
  • package(打包):就是我们常用的 jar 包、war 包。
  • install(安装):把一个 Maven 项目打包 jar 包后存入到 Maven 仓库。
  • deploy(部署):把 jar 包部署到 Nexus 私服上,可以上其他开始人员使用。

什么是 Maven 的依赖

Maven 的依赖功能是是我们使用 Maven 的主要原因,我们使用 Maven 的依赖管理,Maven 的依赖管理帮我们解决了 jar 包的下载,同时可以把项目中的依赖进行传递或把某些不需要依赖进行排除。

Maven 的下载安装

Maven 官网下载页面

在这里插入图片描述

Maven 下载解压后如下:
在这里插入图片描述

配置本地 Maven 仓库,Maven 默认的本地仓库目录是:用户目录/.m2/repository,一般都会自己指定一个本地仓库目录,自己指定 Maven 本地仓库目录需要修改 conf 目录下的 settings.xml 文件,如下:

  <!-- localRepository
   | The path to the local repository maven will use to store artifacts.
   |
   | Default: ${user.home}/.m2/repository
  <localRepository>/path/to/local/repo</localRepository>
  -->
 

 <localRepository>D:\tool\maven\repository</localRepository>

Maven 的坐标(dependency)

Maven 中的坐标使用三个向量 groupId、artifactId、version 在 Maven 的仓库中唯一的定位到一个 jar 包。

  • groupId:一般是公司的域名或者简称,例如:com.alibaba。
  • artifactId:一般是项目或者模块的名称,例如:order-server。
  • version:版本号。

dependency 除了以上三个属性还有一个属性 scope,scope 表示依赖的范围,scope 的值有、compile、provide、runtime、test、system,具体如下:

  • compile:编译范围,该范围为默认依赖范围,编译范围的依赖会用在编译,测试,运行,由于运行时需要,所以编译范围的依赖会被打包。
  • provide:provied 依赖只有当 JDK 或者 Tomcat 已提供该依赖之后才使用,provide 依赖在编译和测试时需要,在运行时不需要,因为运行时候 JDK 或者 Tomcat 已经提供了。
  • runtime:runtime 依赖在运行和测试系统时需要,但在编译时不需要,由于运行时需要,所以 runtime 范围的依赖会被打包。
  • test:test 范围依赖在编译和运行时都不需要,只在测试编译和测试运行时需要,因此 test 范围的依赖不会被打包。
  • system:system 范围依赖与 provide 类似,但是必须显示的提供一个对于本地系统中 jar 文件的路径,一般不推荐使用。

Maven 标签在 pom 文件中的使用

一个简单的项目的 pom 文件的核心配置如下:

<!-- 当前 Maven 项目的坐标 -->
<groupId>com.demo</groupId>
<artifactId>demo</artifactId>
<version>1.0-SNAPSHOT</version>
<name>demo</name>
<description>Demo project for Spring Boot</description>
<!-- 当前 Maven 项目的打包方式 有 jar  war  pom 三种方式-->
<!-- jar:表示这个项目是一个Java项目  -->
<!-- war:表示这个项目是一个Web项目 -->
<!-- pom:表示这个项目是父项目 -->
<packaging>jar</packaging>
<properties>
    <!-- 项目构建过程中读取源码时使用的字符集 -->
    <project.build.sourceEncoding>UTF-8</project.build.sourceEncoding>
</properties>
<!-- 当前项目所依赖的jar包 -->
<dependencies>
    <!-- 使用 dependency 配置一个具体的依赖 -->
    <dependency>
        <!-- 在dependency标签内使用具体的坐标依赖我们需要的一个jar包 -->
        <groupId>com.alibaba.cloud</groupId>
        <artifactId>spring-cloud-starter-alibaba-nacos-config</artifactId>
        <version>2021.1</version>
        <!-- scope标签配置依赖的范围 compile 默认的可以不写-->
        <scope>compile</scope>
			<!-- 使用 excludes 标签排除不需要的依赖	-->
			<exclusions>
				<!-- 在 exclude 标签中配置一个具体的排除 -->
				<exclusion>
					<!-- 指定要排除的依赖的坐标  这里无需要写version -->
					<groupId>org.springframework.cloud</groupId>
					<artifactId>spring-cloud-netflix-ribbon</artifactId>
				</exclusion>
			</exclusions>
    </dependency>
</dependencies>

Maven 管理父子项目

创建父项目

在这里插入图片描述

demo-parent 项目 pom.xml 文件如下:

<?xml version="1.0" encoding="UTF-8"?>
<project xmlns="http://maven.apache.org/POM/4.0.0"
         xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
         xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd">
    <modelVersion>4.0.0</modelVersion>

    <groupId>com.my.study</groupId>
    <artifactId>demo-parent</artifactId>
    <version>1.0-SNAPSHOT</version>
	<!-- 当前项目是父项目 打包方式是 pom -->
    <packaging>pom</packaging>

    <properties>
        <maven.compiler.source>8</maven.compiler.source>
        <maven.compiler.target>8</maven.compiler.target>
    </properties>

</project>

创建子项目

在这里插入图片描述

子项目 pom.xml 文件

<?xml version="1.0" encoding="UTF-8"?>
<project xmlns="http://maven.apache.org/POM/4.0.0"
         xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
         xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd">
    <!-- 当前项目的父项目-->
    <parent>
        <artifactId>demo-parent</artifactId>
        <groupId>com.my.study</groupId>
        <version>1.0-SNAPSHOT</version>
    </parent>
    <modelVersion>4.0.0</modelVersion>
	<!-- 子项目的 artifactId -->
    <artifactId>demo-child</artifactId>

    <properties>
        <maven.compiler.source>8</maven.compiler.source>
        <maven.compiler.target>8</maven.compiler.target>
    </properties>

</project>

此时再看父项目的 pom.xml 文件

<?xml version="1.0" encoding="UTF-8"?>
<project xmlns="http://maven.apache.org/POM/4.0.0"
         xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
         xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd">
    <modelVersion>4.0.0</modelVersion>

    <groupId>com.my.study</groupId>
    <artifactId>demo-parent</artifactId>
    <version>1.0-SNAPSHOT</version>
    
    <!-- 被父项目管理的子项目 -->
	<modules>
        <module>demo-child</module>
        <!-- 这里可以有多个子项目 -->
    </modules>
	
	<!-- 当前项目是父项目 打包方式是 pom -->
    <packaging>pom</packaging>

    <properties>
        <maven.compiler.source>8</maven.compiler.source>
        <maven.compiler.target>8</maven.compiler.target>
    </properties>

</project>

modules 标签是管理子项目的标签。

父项目自定义属性

同一个系统的各个子项目依赖的 jar 包最好使用相同的版本,为了方便版本的管理,我们可以将 jar 的版本号信息维护在父项目中,通过自定义属性来实现,子项目引用父项目中的依赖信息时,可以把版本号去掉,自定义版本号如下:

<properties>
    <!-- 通过自定义属性,统一指定 Spring alibaba Cloud的版本 -->
    <spring.alibaba.cloud.version>2021.1</spring.alibaba.cloud.version>
</properties>

在需要使用的地方使用 ${} 的形式来引用自定义的属性名,如下:

<!--引入 sentinel 支持-->
<dependency>
	<groupId>com.alibaba.cloud</groupId>
	<artifactId>spring-cloud-starter-alibaba-sentinel</artifactId>
	<version>${spring.alibaba.cloud.version}</version>
</dependency>

build 标签

build 标签由三个子标签组成,分别是目录结构标签(有好几个标签)、插件管理标签(pluginManagement) 、插件标签(plugins),具体如下:

  • 目录结构标签(有好几个标签):用来定义项目的结构,项目中一定会用到的标签。
  • 插件管理标签(pluginManagement):管理一些插件,项目中很少用到。
  • 插件标签(plugins):管理一些插件,项目中一定会用到的标签。

目录结构标签

  • sourceDirectory:程序代码存放目录。
  • scriptSourceDirectory:脚本存放目录。
  • testSourceDirectory:测试代码存放目录。
  • outputDirectory:程序代码编译结果输出目录。
  • testOutputDirectory:测试代码编译输出目录。
  • resources:资源文件存储目录(后面详细讲解)。
  • testResources:测试资源文件存放目录。
  • directory:构建结果输出目录。
<build>
	<finalName>demo-child</finalName>
	<sourceDirectory>//</sourceDirectory>
	<scriptSourceDirectory>//</scriptSourceDirectory>
	<testSourceDirectory>//</testSourceDirectory>
	<outputDirectory>//</outputDirectory>
	<testOutputDirectory>//</testOutputDirectory>
</build>

插件管理标签

  • maven-antrun-plugin:主要是执行一些 ant 任务,在 Maven 还没诞生的时候 Java 代码主要编译工具是 ant,因此为了要兼容老的 ant 编译,使用 maven-antrun-plugin 就能完成。
  • maven-assembly-plugin:是 Maven 中针对打包任务而提供的标准插件,可以实现自定义打包。
  • maven-jar-plugin:maven 生命周期 package 阶段的默认打包插件,当不想对该插件进行自定义配置时,就不用在 pom.xml 中主动声明该插件。
  • maven-dependency-plugin:是一个依赖管理插件,大部分情况下我们使用它都是和 maven-jar-plugin 配合来使用,将项目的执行 jar 和依赖的 jar 进行分离管理,这样可以减少项目执行 jar 的大小。
  • maven-release-plugin:主要作用是在 Maven 项目中执行版本发布流程的插件,它的主要功能是简化项目版本的发布和管理,确保版本号的正确性,并自动处理与版本发布相关的任务。

插件标签

plugin 定义插件的标签,插件也是通过坐标定义的,项目中常用的插件如 maven-deploy-plugin、spring-boot-maven-plugin 插件等,其中 spring-boot-maven-plugin 插件不是 maven 自带的插件,使用 maven 自带的打包插件 maven-jar-plugin 打出来的 jar 包不会把依赖 jar 一起打进去,是一个普通 jar 包,无法使用 java -jar 进行启动,因此 Spring Boot 提供了 spring-boot-maven-plugin 插件来打包。

<plugins>
	<!--plugin 表示我是一个插件-->
	<plugin>
		<!--插件的坐标 groupId artifactId version -->
		<!--spring-boot-maven-plugin 打包插件 使用此插件在打Jar包时会引入依赖包-->
		<groupId>org.springframework.boot</groupId>
		<artifactId>spring-boot-maven-plugin</artifactId>
		<version>3.3.1</version>
	</plugin>
	<!--maven-deploy-plugin 将项目部署到 maven 仓库-->
	<plugin>
		<groupId>org.apache.maven.plugins</groupId>
		<artifactId>maven-deploy-plugin</artifactId>
		<configuration>
			<skip>true</skip>
		</configuration>
	</plugin>
</plugins>

resources 标签详解

通常情况下,maven 项目中默认资源文件在 src/main/resources 和 src/test/resources 目录下,但是会有一下特殊情况:

  • 需要添加 src/main/resources 目录外的的配置文件。
  • 只需要 src/main/resources 目录中的部分配置文件。
  • 需要对 src/main/resources 中配置文件的变量,进行placeholder进行解析值替换。

resources 标签示例如下:

<build>
	<resources>
		<resource>
			<!--资源文件目录-->
			<directory>src/main/resources</directory>
			<!--打包时候是否进行变量替换-->
			<filtering>false</filtering>
			<!--仅某些文件被打包-->
			<includes>
				<include>application.properties</include>
				<!-- **表示任意目录,*.*表示任意文件名和扩展名-->
                <include>**/*.*</include>
			</includes>
			<!--指定哪些文件不被打包-->
			<excludes>
				<exclude>application.yaml</exclude>
			</excludes>
		</resource>
	</resources>
</build>

resources 中各个标签的含义

  • :指定资源目录。
  • :指定资源文件目录中,哪些文件被打包。
  • :指定资源文件目录中,哪些文件不被打包。
  • :是一个 boolean 值,默认值为 false,指定打包时的配置文件中是否进行变量替换。

使用 filtering 完成变量替换

src/main/resources 下 application.properties 文件配置如下:

application.username=${username}
application.password=${password}

在 pom .xml 文件中定义变量如下:

<properties>
	<username>mysql</username>
	<password>password123</password>
</properties>

对配置文件中变量进行替换,给 标签复制为 true。

<resource>
	<directory>src/main/resources</directory>
	<includes>
		<include>application.properties</include>
	</includes>
	<filtering>true</filtering>
</resource>

注意:includes 和 excludes 标签同时使用的时候取交集,一般情况下单独使用其中一个即可满足要求。

profile 标签

profile 标签是环境配置标签,通常情况下我们的项目运行有三种环境,开发、测试、生产环境,我们使用 profile 标签可以完成多环境管理,profile 标签多环境配置如下:

<build>
    <!-- profile对资源的操作 -->
    <resources>
        <resource>
            <directory>src/main/resources</directory>
            <!-- 先排除所有环境相关的配置文件 -->
            <excludes>
                <exclude>application*.yml</exclude>
            </excludes>
        </resource>
        <resource>
            <directory>src/main/resources</directory>
            <!--通过开启 filtering -->
            <filtering>true</filtering>
            <includes>
                <include>application.yml</include>
                <include>application-${profileActive}.yml</include>
            </includes>
        </resource>
    </resources>
</build>


<!--多环境文件配置-->
<profiles>
    <!--开发环境-->
    <profile>
        <id>dev</id>
        <activation>
            <!--默认激活-->
            <activeByDefault>true</activeByDefault>
        </activation>
        <properties>
            <profileActive>dev</profileActive>
        </properties>
    </profile>
    <!--测试环境-->
    <profile>
        <id>test</id>
        <properties>
            <profileActive>test</profileActive>
        </properties>
    </profile>
    <!--正式环境-->
    <profile>
        <id>prod</id>
        <properties>
            <profileActive>prod</profileActive>
        </properties>
    </profile>
</profiles>

我们可以在 application.yml 中配置如下:

spring.profiles.active='@profileActive@'

profileActive是我们在 pom.xml 中配置的文件,这样就可以完成不同环境的配置。

Maven 常用命令

  • mvn clean:清除 target 目录。
  • mvn compile:编译 main 目录。
  • mvn test:执行所有的测试方法。
  • mvn package:打包命令,打包当前的项目到 target 目录。
  • mvn install:打包并且发布到本地仓库。
  • mvn install -Dmaven.test.skip=true:只打包不测试(跳过测试)。

如有不正确的地方请各位指出纠正。

;