介绍

maven最主要的3个功能

  1. 提供标准化的项目结构

  2. 依赖管理

  3. 提供标准化的构建流程

怎么找到对应的项目地址:

如果我们要引用一个第三方组件,比如okhttp,如何确切地获得它的groupIdartifactIdversion?方法是通过search.maven.org搜索关键字,找到对应的组件后,直接复制:

提供标准化的项目结构

  • a-maven-project:是项目名

  • pom.xml:是管理依赖的pom文件

  • src-main-java:是核心代码

  • ser-main-resource:是生产环境的配置

  • src-test-java:一般都是测试类

  • src-test-resource:是测试环境的配置

当运行test-java下的测试类时,是优先使用测试环境的配置(即测试环境的配置优先级高于生产环境的配置)

模块管理

Maven可以有效地管理多个模块,我们只需要把每个模块当作一个独立的Maven项目,它们有各自独立的pom.xml。例如,模块A的pom.xml

 <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.itranswarp.learnjava</groupId>
     <artifactId>module-a</artifactId>
     <version>1.0</version>
     <packaging>jar</packaging>
 ​
     <name>module-a</name>
 ​
     <properties>
         <project.build.sourceEncoding>UTF-8</project.build.sourceEncoding>
         <project.reporting.outputEncoding>UTF-8</project.reporting.outputEncoding>
         <maven.compiler.source>11</maven.compiler.source>
         <maven.compiler.target>11</maven.compiler.target>
         <java.version>11</java.version>
     </properties>
 ​
     <dependencies>
         <dependency>
             <groupId>org.slf4j</groupId>
             <artifactId>slf4j-api</artifactId>
             <version>1.7.28</version>
         </dependency>
         <dependency>
             <groupId>ch.qos.logback</groupId>
             <artifactId>logback-classic</artifactId>
             <version>1.2.3</version>
             <scope>runtime</scope>
         </dependency>
         <dependency>
             <groupId>org.junit.jupiter</groupId>
             <artifactId>junit-jupiter-engine</artifactId>
             <version>5.5.2</version>
             <scope>test</scope>
         </dependency>
     </dependencies>
 </project>

模块B的pom.xml

 <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.itranswarp.learnjava</groupId>
     <artifactId>module-b</artifactId>
     <version>1.0</version>
     <packaging>jar</packaging>
 ​
     <name>module-b</name>
 ​
     <properties>
         <project.build.sourceEncoding>UTF-8</project.build.sourceEncoding>
         <project.reporting.outputEncoding>UTF-8</project.reporting.outputEncoding>
         <maven.compiler.source>11</maven.compiler.source>
         <maven.compiler.target>11</maven.compiler.target>
         <java.version>11</java.version>
     </properties>
 ​
     <dependencies>
         <dependency>
             <groupId>org.slf4j</groupId>
             <artifactId>slf4j-api</artifactId>
             <version>1.7.28</version>
         </dependency>
         <dependency>
             <groupId>ch.qos.logback</groupId>
             <artifactId>logback-classic</artifactId>
             <version>1.2.3</version>
             <scope>runtime</scope>
         </dependency>
         <dependency>
             <groupId>org.junit.jupiter</groupId>
             <artifactId>junit-jupiter-engine</artifactId>
             <version>5.5.2</version>
             <scope>test</scope>
         </dependency>
     </dependencies>
 </project>

可以看出来,模块A和模块B的pom.xml高度相似,因此,我们可以提取出共同部分作为parent

 <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.itranswarp.learnjava</groupId>
     <artifactId>parent</artifactId>
     <version>1.0</version>
     <packaging>pom</packaging>
 ​
     <name>parent</name>
 ​
     <properties>
         <project.build.sourceEncoding>UTF-8</project.build.sourceEncoding>
         <project.reporting.outputEncoding>UTF-8</project.reporting.outputEncoding>
         <maven.compiler.source>11</maven.compiler.source>
         <maven.compiler.target>11</maven.compiler.target>
         <java.version>11</java.version>
     </properties>
 ​
     <dependencies>
         <dependency>
             <groupId>org.slf4j</groupId>
             <artifactId>slf4j-api</artifactId>
             <version>1.7.28</version>
         </dependency>
         <dependency>
             <groupId>ch.qos.logback</groupId>
             <artifactId>logback-classic</artifactId>
             <version>1.2.3</version>
             <scope>runtime</scope>
         </dependency>
         <dependency>
             <groupId>org.junit.jupiter</groupId>
             <artifactId>junit-jupiter-engine</artifactId>
             <version>5.5.2</version>
             <scope>test</scope>
         </dependency>
     </dependencies>
 </project>

注意到parent的<packaging>pom而不是jar,因为parent本身不含任何Java代码。编写parentpom.xml只是为了在各个模块中减少重复的配置。现在我们的整个工程结构如下:

 multiple-project
 ├── pom.xml
 ├── parent
 │   └── pom.xml
 ├── module-a
 │   ├── pom.xml
 │   └── src
 ├── module-b
 │   ├── pom.xml
 │   └── src
 └── module-c
     ├── pom.xml
     └── src

这样模块A就可以简化为:

 <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>
 ​
     <parent>
         <groupId>com.itranswarp.learnjava</groupId>
         <artifactId>parent</artifactId>
         <version>1.0</version>
         <relativePath>../parent/pom.xml</relativePath>
     </parent>
 ​
     <artifactId>module-a</artifactId>
     <packaging>jar</packaging>
     <name>module-a</name>
 </project>

模块B、模块C都可以直接从parent继承,大幅简化了pom.xml的编写。

父模块 <packaging>pom</packaging>,指明module,还可以定义依赖管理(<dependencyManagement>)、插件管理(<pluginManagement>)等,这些配置会被子模块继承。

     <modules>
         <module>app-asso-service-model</module>
         <module>app-asso-api</module>
     </modules>

子模块 <packaging>jar</packaging>,并且还要指明parent

     <parent>
         <groupId>com.itranswarp.learnjava</groupId>
         <artifactId>parent</artifactId>
         <version>1.0</version>
         <relativePath>../parent/pom.xml</relativePath>
     </parent>

依赖管理

pom文件

 <?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 https://maven.apache.org/xsd/maven-4.0.0.xsd">
     
     <modelVersion>4.0.0</modelVersion>
     
     <groupId>com.ludan</groupId>
     <artifactId>app-asso-api</artifactId>
     <version>1.1.0.RELEASE</version>
 ​
     <name>app-asso-api</name>
     <packaging>jar</packaging>
     <description>Demo project for Spring Boot</description>
 ​
     <parent>
         <groupId>com.ludan</groupId>
         <artifactId>app-asso-service</artifactId>
         <version>1.0.0.RELEASE</version>
     </parent>
 ​
     <dependencies>
         <dependency>
             <groupId>com.ludan</groupId>
             <artifactId>ludan-common-spring-boot-starter</artifactId>
         </dependency>
         <dependency>
             <groupId>org.springframework.boot</groupId>
             <artifactId>spring-boot-starter-data-jpa</artifactId>
         </dependency>
 ​
         <dependency>
             <groupId>com.arangodb</groupId>
             <artifactId>arangodb-spring-data</artifactId>
             <version>3.5.0</version>
         </dependency>
     </dependencies>
 ​
 ​
     <distributionManagement>
         <repository>
             <id>nexus-releases</id>
             <name>releases Repository</name>
             <url>http://47.104.201.245:8084/nexus/repository/maven-releases/</url>
         </repository>
 ​
         <snapshotRepository>
             <id>nexus-snapshots</id>
             <url>http://47.104.201.245:8084/nexus/repository/maven-snapshots/</url>
             <uniqueVersion>true</uniqueVersion>
         </snapshotRepository>
     </distributionManagement>
 ​
 </project>

固定结构

<?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 https://maven.apache.org/xsd/maven-4.0.0.xsd">
    
    <modelVersion>4.0.0</modelVersion>
    
</project>
  1. <?xml version="1.0" encoding="UTF-8"?> :表示这是XML文件,编码采用UTF-8

  2. xmlns指定了POM文件的命名空间,告诉工具这是Maven 4.0.0版本的POM。

  3. xsi:schemaLocation定义了XML Schema的位置,用于校验POM的结构和内容是否符合规范。

  4. <modelVersion>4.0.0</modelVersion>表示使用的 Maven POM 模型版本,一般固定为 4.0.0,这是 Maven 当前版本所支持的标准。

项目坐标(Project Coordinates)

    <groupId>com.ludan</groupId>
    <artifactId>app-asso-api</artifactId>
    <version>1.1.0.RELEASE</version>
  • groupId:组织 ID,用于区分不同组织或公司。(这里就是ludan.com的反过来,那百度的就是com.baidu)

  • artfactId:项目/模块的唯一名称。(一般放在哪个模块下,就和模块名称一致)

  • version:项目版本号,1.0.0.RELEASE 通常代表正式发布版本。(版本)

父pom

    <parent>
        <groupId>com.ludan</groupId>
        <artifactId>central-platform</artifactId>
        <version>4.6.7-RELEASE</version>
        <relativePath></relativePath>
    </parent>

这里指该pom继承了一个父pom,这个父pom项目坐标

依赖

    <dependencies>
        <dependency>
            <groupId>com.ludan</groupId>
            <artifactId>ludan-common-spring-boot-starter</artifactId>
        </dependency>
        <dependency>
            <groupId>org.springframework.boot</groupId>
            <artifactId>spring-boot-starter-data-jpa</artifactId>
        </dependency>

        <dependency>
            <groupId>com.arangodb</groupId>
            <artifactId>arangodb-spring-data</artifactId>
            <version>3.5.0</version>
        </dependency>
    </dependencies>

这里都是包含了依赖的项目坐标

properties

	<properties>
        <project.build.sourceEncoding>UTF-8</project.build.sourceEncoding>
		<maven.compiler.release>17</maven.compiler.release>
	</properties>
  • project.build.sourceEncoding:表示项目源码的字符编码,通常应设定为UTF-8

  • maven.compiler.release:表示使用的JDK版本,例如21

依赖传递

依赖关系

Maven定义了几种依赖关系,分别是compiletestruntimeprovided

scope

说明

示例

compile

编译时需要用到该jar包(默认)

commons-logging

test

编译Test时需要用到该jar包

junit

runtime

编译时不需要,但运行时需要用到

mysql

provided

编译时需要用到,但运行时由JDK或某个服务器提供

servlet-api

其中,默认的compile是最常用的,Maven会把这种类型的依赖直接放入classpath。

test依赖表示仅在测试时使用,正常运行时并不需要。最常用的test依赖就是JUnit:

<dependency>
    <groupId>org.junit.jupiter</groupId>
    <artifactId>junit-jupiter-api</artifactId>
    <version>5.3.2</version>
    <scope>test</scope>
</dependency>

runtime依赖表示编译时不需要,但运行时需要。最典型的runtime依赖是JDBC驱动,例如MySQL驱动:

<dependency>
    <groupId>mysql</groupId>
    <artifactId>mysql-connector-java</artifactId>
    <version>5.1.48</version>
    <scope>runtime</scope>
</dependency>

provided依赖表示编译时需要,但运行时不需要。最典型的provided依赖是Servlet API,编译的时候需要,但是运行时,Servlet服务器内置了相关的jar,所以运行期不需要:

<dependency>
    <groupId>jakarta.servlet</groupId>
    <artifactId>jakarta.servlet-api</artifactId>
    <version>4.0.0</version>
    <scope>provided</scope>
</dependency>

一般我们不会在后面加scope,默认的时compile,这包含了全部时期

<dependency>
    <groupId>jakarta.servlet</groupId>
    <artifactId>jakarta.servlet-api</artifactId>
    <version>4.0.0</version>
</dependency>

标准化的构建流程

clean:删除target目录下编译后的文件或Jar包,以及日志文件

compile:将Java文件编译成class文件,并且放入target中(java下的文件会放在target/classes下)(test中的java文件不会)

在这过程中,还会处理一些注解(比如说你一个实体类上加了Data注解,那么编译就会自动把get和set方法加上去)

为啥感觉平时我不用编译也可以运行呢?

这其实是因为IDEA在你编写完java文件后自动帮你编译了。只有class文件才可以翻译成机器码进行运行的

test:将test中的java文件编译,并且全部运行测试,(如果没有compile,那会先运行compile,是一个依赖的关系)并且放在test-classes上

package:将项目打包,但是默认的话是模块分别打包,不会合并成同一个

verify:verify 阶段是用于验证包的完整性和正确性,确保生成的构件(如 JAR 文件)符合预期的质量标准。这个阶段是构建过程中的一个重要步骤,通常在 package 阶段之后执行。

install:install 阶段是将构建生成的构件(如 JAR 文件)安装到本地 Maven 仓库中。

site:site 生命周期用于生成项目的站点文档。这些文档通常包括项目的概述、依赖关系、测试报告、代码覆盖率报告等,为项目的文档化和报告提供了全面的支持。

deploy:deploy 阶段是将构建生成的构件(如 JAR 文件)部署到远程仓库中。

比较是偷走幸福的小偷