Maven基础
Maven就是是专门为Java项目打造的管理和构建工具,它的主要功能有
- 提供了一套标准化的项目结构;
- 提供了一套标准化的构建流程(编译,测试,打包,发布……);
- 提供了一套依赖管理机制
结构
根项目名称:a-maven-project
项目描述pom.xml
存放源码src/main/java
存放资源src/main/resources
存放测试源码src/test/java
存放测试资源src/test/resources
编译、打包生成的文件target
pom.xml
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17
| <project ...> <modelVersion>4.0.0</modelVersion> <groupId>com.itranswarp.learnjava</groupId> <artifactId>hello</artifactId> <version>1.0</version> <packaging>jar</packaging> <properties> ... </properties> <dependencies> <dependency> <groupId>commons-logging</groupId> <artifactId>commons-logging</artifactId> <version>1.2</version> </dependency> </dependencies> </project>
|
groupId
类似Java包名,通常是公司或组织名
artifactId
类似于Java的类名
version
引入第三方库,也是通过这三个变量确定
<dependency>
声明依赖,Maven会自动下载依赖包并放在classpath
依赖管理
Maven第一个作用就是解决依赖管理,如我们需要abc包,而abc依赖xyz包,Maven会自动导入依赖包。
Maven定义了几种依赖关系
compile
编译时需要用的该jar包(默认), 如commons-logging
test
编译Test需要用到,如junit
runtime
编译时不需要,运行时需要 如mysql
provided
编译时需要,但由JDK或服务器提供 如servlet-api
1 2 3 4 5 6
| <dependency> <groupId>javax.servlet</groupId> <artifactId>javax.servlet-api</artifactId> <version>4.0.0</version> <scope>provided</scope> </dependency>
|
Maven维护一个中央仓库(repo1.maven.org),所有第三方库将自身的jar
以及相关信息上产至中央仓库。
- 一旦jar包被下载过,会自动缓存至用户根目录
.m2
下
- 唯一ID,通过
groupId
,artifactId
,version
确定jar包,maven对包使用PGP签名。
SNAPSHOT-
开头的版本号为开发版本, 每次都会重复下载
国内源
在.m2目录下settings.xml设置
1 2 3 4 5 6 7 8 9 10
| <settings> <mirrors> <mirror> <id>aliyun</id> <name>aliyun</name> <mirrorOf>central</mirrorOf> <url>http://maven.aliyun.com/nexus/content/groups/public/</url> <mirror> </mirrors> </settings>
|
如何搜索包
https://search.maven.org/
构建流程
Maven还有一套标准化的构建流程,实现自动化编译,打包,发布等
Lifecycle(生命周期)和Phase(阶段)
Maven的生命周期由一系列阶段构成,以内置的生命周期default
为例,包含以下阶段:
- 运行
mvn package
执行default
生命周期,执行到package
阶段
- 运行
mvn compile
执行default
生命周期,执行到compile
阶段
mvn 阶段
,执行到设定阶段
另一个生命周期clean
,包含以下阶段
- pre-clean
- clean
- Post-cleam
多阶段执行mvn clean package
, 先执行clean生命周期的clean阶段,然后执行default的package阶段
Goal(执行阶段的具体方法)
执行一个phase会触发一个或多个Goal,明明形式abc:xyz
少数情况需要执行运行goal,例如启动tomcat服务器
mvn tomcat:run
使用插件
实际上,执行每个phase
,都是通过某个插件(plugin)来执行,比如mvn compile
Maven本身并不知道如何执行,它只是负责找到对应的compiler
插件,然后执行默认的compiler:compile
这个goal来完成编译
自定义插件
使用自定义插件的时候,需要声明。例如,使用maven-shade-plugin
可以创建一个可执行的jar,要使用这个插件,需要在pom.xml
中声明它
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23
| <project> ... <build> <plugins> <plugin> <groupId>org.apache.maven.plugins</groupId> <artifactId>maven-shade-plugin</artifactId> <version>3.2.1</version> <executions> <execution> <phase>package</phase> <goals> <goal>shade</goal> </goals> <configuration> ... </configuration> </execution> </executions> </plugin> </plugins> </build> </project>
|
自定义插件往往需要一些配置,例如,maven-shade-plugin
需要指定Java程序的入口,它的配置是:
1 2 3 4 5 6 7
| <configuration> <transformers> <transformer implementation="org.apache.maven.plugins.shade.resource.ManifestResourceTransformer"> <mainClass>com.itranswarp.learnjava.Main</mainClass> </transformer> </transformers> </configuration
|
Maven自带的标准插件例如compiler
是无需声明的,只有引入其它的插件才需要声明。
下面列举了一些常用的插件:
- maven-shade-plugin:打包所有依赖包并生成可执行jar;
- cobertura-maven-plugin:生成单元测试覆盖率报告;
- findbugs-maven-plugin:对Java源码进行静态分析以找出潜在问题。
模块管理
Maven支持模块化管理,可以把一个大项目拆成几个模块:
- 可以通过继承在parent的
pom.xml
统一定义重复配置;
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40
| <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>
|
模块A继承parent
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16
| <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>parent</artifactId> <packaging>jar</packaging> <name>module-a</name> </project>
|
- Maven根据根目录的
pom.xml
找到包括parent
在内的共4个``,一次性全部编
使用mvnw
mvnw
是Maven Wrapper缩写,作用是只针对特定的项目安装特定斑斑的Maven,而不影响其他项目。
安装Maven Wrapper(官网)最简单的方式是在项目的根目录(即pom.xml
所在的目录)下运行安装命令:
1
| mvn -N io.takari:maven:0.7.6:wrapper //使用最新版本的Maven,0.7.6是mvnw版本
|
如果要指定使用的Maven版本,使用下面的安装命令指定版本,例如3.3.3
:
1
| mvn -N io.takari:maven:0.7.6:wrapper -Dmaven=3.3.3
|
发现多了mvnw
、mvnw.cmd
和.mvn
目录,我们只需要把mvn
命令改成mvnw
就可以使用跟项目关联的Maven。