介绍
maven最主要的3个功能
提供标准化的项目结构
依赖管理
提供标准化的构建流程
怎么找到对应的项目地址:
如果我们要引用一个第三方组件,比如okhttp
,如何确切地获得它的groupId
、artifactId
和version
?方法是通过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代码。编写parent
的pom.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>
<?xml version="1.0" encoding="UTF-8"?> :
表示这是XML文件,编码采用UTF-8xmlns
指定了POM文件的命名空间,告诉工具这是Maven 4.0.0版本的POM。xsi:schemaLocation
定义了XML Schema的位置,用于校验POM的结构和内容是否符合规范。<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定义了几种依赖关系,分别是compile
、test
、runtime
和provided
:
其中,默认的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 文件)部署到远程仓库中。