Maven
What is Maven?
- 构建规范项目的工具
- 项目管理工具,进行打包,测试,部署
- 具有一套规范
POM
What is POM
- Maven 的基本工作单元
- xml 文件
- 存储 Maven 项目的配置文件(Maven 的命令都是先从 POM 读取命令,然后执行命令)
Super POM
Maven 的默认 POM 文件,如果 POM 文件没有指定父 POM 文件,那么配置都是集成 Super POM
Minimal POM
POM 文件的最低需要的配置元素:
- project
- groupId: 一般是组织名称
- artifactId: 项目的名称
- version: 项目的版本号
Maven 项目的完全限定名:
groupId:artifactId:version
packaging 元素默认是 JAR, 还有其他选项是 WAR,EAR 等等
Project Inheritance
之前在 Super POM 一节谈到指定了父 POM 的继承指定父 POM 的配置,实现如下:
.
|--my-app
| |-- my-module
| | `-- pom.xml
`-- pom.xml
my-app 的 POM
<project>
<modelVersion>4.0.0</modelVersion>
<groupId>com.mycompany.app</groupId>
<artifactId>my-app</artifactId>
<version>1</version>
</project>
my-module 的 POM
<project>
<modelVersion>4.0.0</modelVersion>
<groupId>com.mycompany.app</groupId>
<artifactId>my-module</artifactId>
<version>1</version>
</project>
修改 my-module 的 POM,即可实现讲 my-app 作为一个父 POM 继承给 my-module,实现如下:
my-module 的 POM
<project>
<parent>
<groupId>com.mycompany.app</groupId>
<artifactId>my-app</artifactId>
<version>1</version>
</parent>
<modelVersion>4.0.0</modelVersion>
<groupId>com.mycompany.app</groupId>
<artifactId>my-module</artifactId>
<version>1</version>
</project>
如果 my-app 不是作为 my-module 的父目录,如下:
.
|-- my-module
| `-- pom.xml
`-- my-app
`-- pom.xml
需要配置 <relativePath> 属性,配置相对 my-module 的相对路径如下:
<project>
<parent>
<groupId>com.mycompany.app</groupId>
<artifactId>my-app</artifactId>
<version>1</version>
<relativePath>../parent/pom.xml</relativePath>
</parent>
<modelVersion>4.0.0</modelVersion>
<artifactId>my-module</artifactId>
</project>
Project Aggregation
如果我们想要对一些模块都需要执行相同的命令,但是不想进入每一个模块下进行执行命令,可以使用 Aggregation.
目录结构
.
|-- my-module
| `-- pom.xml
`-- pom.xml
将 my-module 模块聚合到 my-app,修改 my-app 的 POM 文件如下:
<project>
<modelVersion>4.0.0</modelVersion>
<groupId>com.mycompany.app</groupId>
<artifactId>my-app</artifactId>
<version>1</version>
<packaging>pom</packaging>
<modules>
<module>my-module</module>
</modules>
</project>
- <packaging> 属性设置未 pom
- <module> 属性是相对于 my-app 的相对路径
- 有些命令不能同时执行
- Inheritance 和 Aggregation 可以混合使用
Project Interpolation and Variables
Maven 的设计哲学就是不要重复自己,所以当一些配置是相同的时候,我们可以使用自己定义的变量和预定义好的变量.
比如我们要使用 projcet 的 version 给其他配置项,我们可以如此使用
<version>${project.version}</version>
我们也可以使用自己定义的变量,比如我们定义了一个 mavenVersion 变量,我们可以如此使用
<project>
...
<properties>
<mavenVersion>2.1</mavenVersion>
</properties>
<dependencies>
<dependency>
<groupId>org.apache.maven</groupId>
<artifactId>maven-artifact</artifactId>
<version>${mavenVersion}</version>
</dependency>
<dependency>
<groupId>org.apache.maven</groupId>
<artifactId>maven-project</artifactId>
<version>${mavenVersion}</version>
</dependency>
</dependencies>
...
</project>
Standard Directory Layout
我们在思考 Maven 是什么的时候,其中有一个理解就是 Maven 是一套规范,那么这些规范体现在哪里呢,体现在他的项目目录的结构
目录 | 解释 |
---|---|
src/main/java | Application/Library sources |
src/main/resources | Application/Library resources |
src/main/filters | Resource filter files |
src/main/webapp | Web application sources |
src/test/java | Test sources |
src/test/resources | Test resources |
src/test/filters | Test resource filter files |
src/it | Integration Tests (primarily for plugins) |
src/assembly | Assembly descriptors |
src/site | Site |
LICENSE.txt | Project’s license |
NOTICE.txt Notices | and attributions required by libraries that the project depends on |
README.txt | Project’s readme |
Compile
- 编译主代码(即是除去测试代码)
命令:
mvn compile
- 切换目录到需要执行编译的项目的 pom.xml 文件目录下
- 首先 Maven 先去下载编译需要的插件和依赖
- 将编译的文件放在${basedir}/target/classed
- 编译测试代码
命令:
mvn test-compile
- 该命令不会进行测试
Test
命令:
mvn test
- 如果没有执行 mvn compile 命令编译,则会先进行编译。
- 同时也需要下载测试需要的插件
install
我们执行编译的或者测试的时候会将需要依赖下载到本地仓库 (一般在 ${user.home}/.m2/repository) 中,供我们的项目使用。那么我们是不是也可以讲自己的项目给其他项目使用呢?
- 先打包
- 后安装
Packaging
命令:
mvn packaging
该命令会将打包好的文件(如果我们在 POM 文件设置 packaging 是 jar,那就打成 jar 包,以此类推)放在目录 ${basedir}/target
Install
命令:
mvn install
surefire 插件会查找项目中特定命名约定的文件
- **/*Test.java
- **/Test*.java
- **/*TestCase.java
默认排除:
- **/Abstract*Test.java
- **/Abstract*TestCase.java
Clean
命令:
mvn clean
只将 ${basedir}/target 里面的文件清除
External Dependencies
命令:
<dependencies>
...
<dependency>
<groupId>com.mycompany.app</groupId>
<artifactId>my-app</artifactId>
<version>1.0-SNAPSHOT</version>
<scope>compile</scope>
</dependency>
</dependencies>
- groupId,artifactId,version 就是我们一开始所说的项目的定位必备三项。
- scope 代表在何时使用一般有个 compile(编译),test(测试),runtime(运行)
- 那么我们引用的这些第三方的库从哪里下载呢?从我们 repository 属性配置
<repositories>
<repository>
<id>central</id>
<name>Central Repository</name>
<url>https://repo.maven.apache.org/maven2</url>
<layout>default</layout>
<snapshots>
<enabled>false</enabled>
</snapshots>
</repository>
</repositories>