maven 简介
Apache Maven,是一个软件(特别是Java软件)项目管理及自动构建工具,由Apache软件基金会所提供。基于项目对象模型(缩写:POM)概念,Maven利用一个中央信息片断能管理一个项目的构建、报告和文档等步骤。—来自维基百科
Maven 是基于项目对象模型(POM),可以通过一小段描述信息来管理项目的构建、报告和文档的软件项目管理工具。
Maven是一款强大的自动化构建工具,覆盖了编译、测试、运行、清理、打包和部署等各个项目构建的周期。它提供了一个仓库的概念,帮助统一的管理第三方的jar包,最大可能避免由于环境配置不同所产生的不同环境无法运行的情况。
maven 环境搭建
Maven 的安装:
- mac下:brew install maven
- windows下:https://maven.apache.org/download.cgi# 找到 Binary zip archive 对应的压缩包下载即可,解压并配置环境变量。
文件结构:
- bin 目录:包含mvn的运行脚本。其中 m2.conf 是一个配置文件。
- boot 目录:包含了一个类加载器的框架plexus-classworlds-2.5.2.jar,maven使用它来加载自己的类库。
- conf 目录:包含了一些配置文件,例如常用的 settings.xml。
- lib 目录:包含了 Maven 运行时所用到的所有类库,除了 Maven自身的,还包含了一些第三方依赖的类库。
maven helloWorld程序
直接使用Idea进行创建,过程如下:
- 创建 maven 项目
- 选择 GroupId 和 ArtifactId
- 确定项目名称及保存地址
查看并修改 pom.xml 内容为:
<?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 http://maven.apache.org/xsd/maven-4.0.0.xsd">
<modelVersion>4.0.0</modelVersion>
<groupId>com.maventest</groupId>
<artifactId>maven.helloworld</artifactId>
<version>1.0-SNAPSHOT</version>
<dependencies>
<dependency>
<groupId>junit</groupId>
<artifactId>junit</artifactId>
<version>4.10</version>
</dependency>
</dependencies>
</project>
- 构建结构目录为:
// HelloWorld.java 文件为:
package com.maventest.helloworld;
public class HelloWorld {
public String sayHello(){
return "Hello World!";
}
}
// HelloWorldTest.java 文件为:
package com.maventest.helloworld;
import org.junit.*;
import org.junit.Assert.*;
public class HelloWorldTest {
@Test
public void testHello(){
Assert.assertEquals("Hello World!", new HelloWorld().sayHello());
}
}
在 terminal 中依次输入如下命令,并观察输出:
- mvn compile
- mvn test
- mvn package
maven 核心知识
maven 常用命令
compile: 编译
test: 测试
package: 打包
clean: 删除target
install: 安装jar包到本地仓库
maven 自动建立目录骨架
archetype插件:用于创建符合 maven 规定的目录骨架。
创建目录的两种方式:
- mav archetype:generate
- mvn archetype:generate -DgroupId=com.imooc.maven04 -DartifactId=maven04-demo -Dversion=1.0.0SNAPSHOT -Dpackage=com.imooc.maven04.demo
maven 中的坐标和仓库
构件:在 maven 中,任何一个插件、依赖以及构件的输出都可以称为构件。
坐标:所有构件均通过构件作为其唯一标识。包括(groupId, artifactId, version)
例如:
- groupId:com.imooc.maven01,其中 com.imooc 为公司名的反写,maven01 为项目名。
- artifactId: maven01-model,其中 maven01 为项目名,model 为该项目的模块名。
- version: 0.0.1SNAPSHOT,为项目所构件的版本
仓库:用来管理项目的依赖。仓库主要分为 本地仓库
和 远程仓库
两种。依赖会先在本地仓库中进行查找,如果查找不到就会在远程仓库进行查找,在远程仓库中能查找到则下载到本地仓库中去,不能查找到则会报错。
maven 全球中央仓库地址:https://repo.maven.apache.org/maven2
修改镜像仓库: 修改 maven/conf/settings.xml 文件。修改下面的内容为:
<mirrors>
<!-- mirror
| Specifies a repository mirror site to use instead of a given repository. The repository that
| this mirror serves has an ID that matches the mirrorOf element of this mirror. IDs are used
| for inheritance and direct lookup purposes, and must be unique across the set of mirrors.
|
<mirror>
<id>maven.net.cn</id>
<mirrorOf>central</mirrorOf>
<name>central mirror in china</name>
<url>http://maven.net.cn/content/groups/public</url>
</mirror>
-->
</mirrors>
仓库位置:${M2_HOME}/conf/settings.xml 文件。
同时将 settings.xml 文件复制一份到 ${user.home}/.m2/settings.xml 文件夹下。
maven的配置文件settings.xml存在于两个地方:
1.安装的地方:${M2_HOME}/conf/settings.xml
2.用户的目录:${user.home}/.m2/settings.xml
前者又被叫做全局配置,对操作系统的所有使用者生效;后者被称为用户配置,只对当前操作系统的使用者生效。如果两者都存在,它们的内容将被合并,并且用户范围的 settings.xml 会覆盖全局的 settings.xml。
Maven安装后,用户目录下不会自动生成 settings.xml,只有全局配置文件。如果需要创建用户范围的 settings.xml,可以将安装路径下的 settings 复制到目录${user.home}/.m2/。Maven默认的settings.xml是一个包含了注释和例子的模板,可以快速的修改它来达到你的要求。
全局配置一旦更改,所有的用户都会受到影响,而且如果 maven 进行升级,所有的配置都会被清除,所以要提前复制和备份 ${M2_HOME}/conf/settings.xml文件,一般情况下不推荐配置全局的 settings.xml。
将复制后的 ${user.home}/.m2/settings.xml 修改下面的内容为:
<localRepository>/path/to/local/repo</localRepository>
即可将仓库指定到 /path/to/local/repo
路径下。
maven 的生命周期和插件
完整的项目构建过程包括:清理、编译、测试、打包、集成测试、验证和部署。
- clean: 清理项目
- pre-clean: 执行清理前的工作
- clean: 清理上一次构建生成的所有文件
- post-clean: 执行清理后的文件
- default: 构建项目(最核心)
- compile:
- test:
- package:
- install:
- site: 生成项目站点
- pre-site: 生成项目站点前要完成工作
- site: 生成项目的站点文档
- post-site: 在生成项目站点后要完成的工作
- site-deploy: 发布生成站点到服务器上
maven 插件:https://maven.apache.org/plugins/index.html 目录下都是 maven 的插件。
例如:使用 source
插件,该插件可以将项目的源码进行打包。
在项目的 pom.xml
文件中,添加一下内容:
<build>
<plugins>
<plugin>
<groupId>org.apache.maven.plugin</groupId>
<artifactId>maven-source-plugin</artifactID>
<version>2,4</version>
<executions>
<phase>package</phase>
<goals>
<goal>jar-no-fork</goal>
</goals>
</executions>
</plugin>
</plugins>
</build>
例如:执行 package 命令时,会默认将前面的 compile, test 命令自动执行。
maven 中 pom.xml 解析
pom,xml 文件是用于项目描述,组织管理,依赖管理和构建信息。
根项目元素:
<project xmlns:'pom的约束信息'>
<!--制定了当前pom的版本-->
<modelVersion></modelVersion>
<groupId>反写的公司网址+项目名</groupId>
<artifactId>项目名+模块名</artifactId>
<!--第一个0表示大版本号
第二个0表示分支版本号
第三个0表示小版本号
0.01
snapshot快照
alpha内部测试
beta公测
release稳定
GA正式发布
-->
<version></version>
<!--默认是jar
war zip pom
-->
<packaging></packaging>
<!--项目描述名,产生文档时会使用-->
<name></name>
<!--项目的地址-->
<url></url>
<!--项目的描述-->
<description></description>
<!--开发人员信息-->
<developers></developers>
<!--许可证件-->
<licenses></licenses>
<!--组织信息-->
<organization></organization>
<!--依赖类-->
<dependencies>
<dependency>
<groupId></groupId>
<artifactId></artifactId>
<veriosn></version>
<type></type>
<!--scope指定依赖的范围
例如junit指定的test, 指的是只在 test 测试过程有用
-->
<scope>test<scope>
<!-- 设置依赖是否可选,默认是 false-->
<optional></optional>
<!--排除依赖传递列表-->
<exclusions>
<exclusion>
</exclusion>
</exclusions>
</dependency>
</dependencies>
<!--依赖的管理,并不会引入依赖-->
<dependencyManagement>
<dependencies>
<dependency>
</dependency>
</dependencies>
</dependencyManagement>
<!--build 对相应的构建行为提供相应的支持-->
<build>
<!--插件列表-->
<plugins>
<plugin>
<groupId></groupId>
<artifactId></artifactId>
<veriosn></version>
</plugin>
</plugins>
</build>
<!-- 对父依赖的继承-->
<parent></parent>
<!-- 指定多个模块。一起编译-->
<modules>
<module></module>
</modules>
</project>
maven 依赖范围
scope 指定6中依赖范围:Dependency Scope
- compile: 默认范围
- provided: 编译测试时有效
- runtime: 测试和运行时有效
- test: 测试时有效
- system: 本机系统相关:编译和测试时有效
- import: 导入的范围
maven 依赖传递
假如 A 依赖于 B,B 依赖于 C。则在 A 引入 B 的依赖时,会将 C 的依赖也引入进来,要想 A 至依赖于 B,可以通过 exclusions
将 C 排除在外:
<exclusions>
<exclusion>
<groupID></groupID>
<artifactId></artifactId>
<version></veriosn>
</exclusion>
</exclusions>
依赖冲突
1 短路优先
A -> B -> C -> X(jar)
A -> D -> X(jar)
假如,A 依赖的 B,D 所依赖的 X 的版本不同,根据短路优先原则,A 会依赖 D 所依赖的 X(jar)
2 路径相同时,先声明先优先
maven 聚合和继承
<parent></parent>
<packaging>pom</packaging>
<modules>
<module></module>
</modules>