MAVEN
Maven专门为Java项目打造的管理和构建工具,它的主要功能有:
提供了一套标准化的项目结构;
提供了一套标准化的构建流程(编译,测试,打包,发布……);
提供了一套依赖管理机制。
Maven项目结构
一个使用Maven管理的普通的Java项目,它的目录结构默认如下:
a-maven-project
├── pom.xml
├── src
│ ├── main
│ │ ├── java
│ │ └── resources
│ └── test
│ ├── java
│ └── resources
└── target
项目的根目录a-maven-project是项目名,
它有一个项目描述文件pom.xml,
存放Java源码的目录是src/main/java,
存放资源文件的目录是src/main/resources,
存放测试源码的目录是src/test/java,
存放测试资源的目录是src/test/resources,
最后,所有编译、打包生成的文件都放在target目录里。
这些就是一个Maven项目的标准目录结构。
所有的目录结构都是约定好的标准结构,我们千万不要随意修改目录结构。使用标准结构不需要做任何配置,Maven就可以正常使用
Maven使用groupId,artifactId和version唯一定位一个依赖
依赖管理
maven会自动加载管理
当一个jar包依赖另外一个jar包时maven会自动获取依赖关系,下载下来
依赖关系
依赖关系
Maven定义了几种依赖关系,分别是compile、test、runtime和provided:
scope 说明 示例
compile 编译时需要用到该jar包(默认) commons-logging
test 编译Test时需要用到该jar包 junit
runtime 编译时不需要,但运行时需要用到 mysql
provided 编译时需要用到,但运行时由JDK或某个服务器提供 servlet-api
其中,默认的compile是最常用的,Maven会把这种类型的依赖直接放入classpath。
test依赖表示仅在测试时使用,正常运行时并不需要。最常用的test依赖就是JUnit:
jar包是从中央仓库下载的,但是中央仓库比较慢。可以配置一个镜像仓库
这个镜像仓库是同步中央仓库的所有包
我们配置镜像仓库只需要修改配置
<settings>
<mirrors>
<mirror>
<id>aliyun</id>
<name>aliyun</name>
<mirrorOf>central</mirrorOf>
<!-- 国内推荐阿里云的Maven镜像 -->
<url>http://maven.aliyun.com/nexus/content/groups/public/</url>
</mirror>
</mirrors>
</settings>
如果想引入一个第三方的jar包怎么搜索maven的坐标呢
网址是search.maven.org
Maven通过lifecycle、phase和goal来提供标准的构建流程
lifecycle就是由下边的阶段组成的
phase
Maven的生命周期由一系列阶段(phase)构成,以内置的生命周期default为例,它包含以下phase:
validate
initialize
generate-sources
process-sources
generate-resources
process-resources
compile
process-classes
generate-test-sources
process-test-sources
generate-test-resources
process-test-resources
test-compile
process-test-classes
test
prepare-package
package
pre-integration-test
integration-test
post-integration-test
verify
install
deploy
如果我们运行mvn package,Maven就会执行default生命周期,它会从开始一直运行到package这个phase为止
那么goal是什么呢
Goal
执行一个phase又会触发一个或多个goal
执行的Phase 对应执行的Goal
compile compiler:compile
test compiler:testCompile
surefire:test
goal的命名总是abc:xyz这种形式。
其实我们类比一下就明白了:
lifecycle相当于Java的package,它包含一个或多个phase;
phase相当于Java的class,它包含一个或多个goal;
goal相当于class的method,它其实才是真正干活的。
大多数情况,我们只要指定phase,就默认执行这些phase默认绑定的goal,只有少数情况,我们可以直接指定运行一个goal,例如,启动Tomcat服务器:
mvn tomcat:run
maven的插件
执行每个phase,都是通过某个插件(plugin)来执行的,Maven本身其实并不知道如何执行compile,
它只是负责找到对应的compiler插件,然后执行默认的compiler:compile这个goal来完成编译。
所以,使用Maven,实际上就是配置好需要使用的插件,然后通过phase调用它们。
Maven已经内置了一些常用的标准插件:
插件名称 对应执行的phase
clean clean
compiler compile
surefire test
jar package
如果标准插件无法满足需求,我们还可以使用自定义插件。
使用自定义插件的时候,需要声明。例如,使用maven-shade-plugin可以创建一个可执行的jar,要使用这个插件,需要在pom.xml中声明它
模块
Maven支持模块化管理,可以把一个大项目拆成几个模块:
可以通过继承在parent的pom.xml统一定义重复配置;
可以通过编译多个模块。
single-project
├── pom.xml
└── src
现在可以分拆成3个模块:
mutiple-project
├── module-a
│ ├── pom.xml
│ └── src
├── module-b
│ ├── pom.xml
│ └── src
└── module-c
| ├── pom.xml
| └── src
├── pom.xml
└── src
Maven可以有效地管理多个模块,我们只需要把每个模块当作一个独立的Maven项目,它们有各自独立的pom.xml。例如,模块A的pom.xml
<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>
<parent>
<groupId>com.itranswarp.learnjava</groupId>
<artifactId>parent</artifactId>
<version>1.0</version>
<relativePath>../parent/pom.xml</relativePath>
</parent>
<artifactId>module-b</artifactId>
<packaging>jar</packaging>
<name>module-b</name>
a 和 b模块儿的共有的依赖都可以放到父pom里
<groupId>com.itranswarp.learnjava</groupId>
<artifactId>parent</artifactId>
<version>1.0</version>
<packaging>pom</packaging> 这个地方是pom不是jar 这个地方是pom不是jar
<name>parent</name>
mvnw
这个可以项目团队内统一使用maven版本,
也可以是个人使用时针对某一个项目用的maven版本
my-project
├── .mvn
│ └── wrapper
│ ├── MavenWrapperDownloader.java
│ ├── maven-wrapper.jar
│ └── maven-wrapper.properties
├── mvnw
├── mvnw.cmd
├── pom.xml
└── src
├── main
│ ├── java
│ └── resources
└── test
├── java
└── resources
mvn -N io.takari:maven:wrapper -Dmaven=3.3.3
distributionUrl=https://repo.maven.apache.org/maven2/org/apache/maven/apache-maven/3.3.3/apache-maven-3.3.3-bin.zip
.mvn/wrapper/maven-wrapper.properties
distributionUrl-指定Maven下载地址
wrapperUrl-指定maven-wrapper.jar的下载地址
使用Maven发布一个Artifact时:
可以发布到本地,然后由静态服务器提供repo服务,使用方必须声明repo地址;
可以发布到central.sonatype.org,并自动同步到Maven中央仓库,需要前期申请账号以及本地配置;
可以发布到GitHub Packages作为私有仓库使用,必须提供Token以及正确的权限才能发布和使用。