# Maven
一个Java项目需要的东西。首先,我们需要确定引入哪些依赖包。例如,如果我们需要用到commons logging,我们就必须把commons logging的jar包放入classpath。如果我们还需要log4j,就需要把log4j相关的jar包都放到classpath中。这些就是依赖包的管理。
其次,我们要确定项目的目录结构。例如,`src`目录存放Java源码,`resources`目录存放配置文件,`bin`目录存放编译生成的`.class`文件。
此外,我们还需要配置环境,例如JDK的版本,编译打包的流程,当前代码的版本号。
最后,除了使用IDE进行编译外,我们还必须能通过命令行工具进行编译,才能够让项目在一个独立的服务器上编译、测试、部署。
Maven是专门的项目管理和构建工具,主要功能:
- 提供了一套标准化的项目结构;
- 提供了一套标准化的构建流程(编译,测试,打包,发布);
- 提供了一套依赖管理机制。
### 下载安装配置
[下载](https://maven.apache.org/)
解压
配置环境变量
配置settings.xml
```xml
aliyun
central
aliyun
https://maven.aliyun.com/repository/central
aliyun
central
aliyun
https://maven.aliyun.com/repository/central
```
IDEA配置Maven
### 项目结构
```bash
a-maven-project
```
项目的根目录`a-maven-project`是项目名,它有一个项目描述文件`pom.xml`,存放Java源码的目录是`src/main/java`,存放资源文件的目录是`src/main/resources`,存放测试源码的目录是`src/test/java`,存放测试资源的目录是`src/test/resources`,最后,所有编译、打包生成的文件都放在`target`目录里。这些就是一个Maven项目的标准目录结构。所有的目录结构都是约定好的标准结构,我们千万不要随意修改目录结构。使用标准结构不需要做任何配置,Maven就可以正常使用。
`pom.xml`
```xml
4.0.0
com.itranswarp.learnjava
hello
1.0
jar
...
commons-logging
commons-logging
1.2
```
其中,`groupId`类似于Java的包名,通常是公司或组织名称,`artifactId`类似于Java的类名,通常是项目名称,再加上`version`,一个Maven工程就是由`groupId`,`artifactId`和`version`作为唯一标识。我们在引用其他第三方库的时候,也是通过这3个变量确定。
使用``声明一个依赖后,Maven就会自动下载这个依赖包并把它放到classpath中。
### 依赖管理
如果我们的项目依赖第三方的jar包,例如commons logging,那么问题来了:commons logging发布的jar包在哪下载?
如果我们还希望依赖log4j,那么使用log4j需要哪些jar包?
类似的依赖还包括:JUnit,JavaMail,MySQL驱动等等,一个可行的方法是通过搜索引擎搜索到项目的官网,然后手动下载zip包,解压,放入classpath。但是,这个过程非常繁琐。
Maven解决了依赖管理问题。例如,我们的项目依赖`abc`这个jar包,而`abc`又依赖`xyz`这个jar包。
当我们声明了`abc`的依赖时,Maven自动把`abc`和`xyz`都加入了我们的项目依赖,不需要我们自己去研究`abc`是否需要依赖`xyz`。
因此,Maven的第一个作用就是解决依赖管理。我们声明了自己的项目需要`abc`,Maven会自动导入`abc`的jar包,再判断出`abc`需要`xyz`,又会自动导入`xyz`的jar包,这样,最终我们的项目会依赖`abc`和`xyz`两个jar包。
```xml
org.springframework.boot
spring-boot-starter-web
1.4.2.RELEASE
```
### 依赖关系
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。
```xml
org.junit.jupiter
junit-jupiter-api
5.3.2
test
```
`runtime`依赖表示编译时不需要,但运行时需要。最典型的`runtime`依赖是JDBC驱动,例如MySQL驱动。
```xml
mysql
mysql-connector-java
5.1.48
runtime
```
`provided`依赖表示编译时需要,但运行时不需要。最典型的`provided`依赖是Servlet API,编译的时候需要,但是运行时,Servlet服务器内置了相关的jar,所以运行期不需要。
```xml
javax.servlet
javax.servlet-api
4.0.0
provided
```
### Maven镜像
使用阿里云镜像,.m2/settings.xml。
```xml
aliyun
aliyun
central
https://maven.aliyun.com/repository/central
```
### 命令行编译
在命令中,进入到`pom.xml`所在目录,输入以下命令
```bash
mvn clean package
```
即可在`target`目录下获得编译后自动打包的jar。