第一章:Maven简介
(1)何为Maven
- 构建工具,依赖管理工具,项目信息管理工具
- 提供免费的中央仓库
- 约定优于配置
(2)其他构建工具
- IDE:如Eclipse,Idea
- Make:最早的构建工具,Makefile的语法
- Ant:Another Neat Tool(另一个整洁的工具),最早用来构建Tomcat。与Maven类似,但是不提供依赖管理
第二章:Maven的安装和配置
(1)安装和配置
(2)配置文件
- $M2_HOME/conf/settings.xml
- 全局范围的,整台机器的所有用户都会受到该配置的影响
- ~/.m2/settings.xml
- 推荐使用!!!
- 用户级别的,不影响其他用户
- 升级Maven不需要重新配置
(3)Maven的文件目录
- bin:包含mvn的运行脚本,对于win来说,是.bat文件
- boot:只包含一个jar文件,Maven使用其加载自己的类库,对用户来说,不用关心该文件
- conf:包含非常重要的settings.xml文件。一般情况下更倾向于复制到~/.m2/目录下,在用户范围内定制Maven的行为
- lib:包含Maven运行时需要的Java类库,以及Maven内置的超级POM
?
第三章:Maven使用入门
(1)生命周期
- mvn clean:清理 target/
- mvn compile:编译项目主代码,到 target/classes 目录
- mvn test:
- mvn package:打包,如果POM中没有指定,默认打jar包,位于target/目录中
- mvn install:将jar包安装到本地repository
(2)如何生成可执行jar包
- 默认打包生成的jar包是不能直接运行的,为了生成可执行的jar包,需要用到 maven-shade-plugin 插件
(3)项目骨架
- Maven中的pom.xml对应于Make中的Makefile,Ant中的build.xml。
- Maven项目的一些约定:src/main/java 目录下放置项目的主代码,src/test/java 目录下放置项目的测试代码,这些基本目录结构和pom.xml被称为项目的骨架
- 快速创建项目骨架
- 首先执行命令:mvn archetype:generate
- 接着按提示输入:groupId, artifactId, version, package

??
第五章:坐标和依赖
(1)Maven的坐标

?
- groupId(必须定义):不关键,比如com.dianping.zebra,或者 com.sankuai.meituan
- artifactId必须定义:项目中的一个模块,推荐用模块名,比如xy-trade-microloan-thrift-api,或者 zebra-client
- version(必须定义):版本,比如 2.9.2-SNAPSHOT
- packaging(可选定义):定义了maven的打包方式,不定义packaging时默认jar包,当然也可以定义war包
- scope(可选定义):作用范围,默认为compile。如果<scope>test</scope>,表示只能在测试代码中import该依赖,主代码依赖会报错
- classifier(不能直接定义):定义一些附属组件,比如【javadoc文档】和【sources源代码】
?(2)Maven依赖
<dependencies>
<dependency>
<groupId>com.dianping.zebra</groupId>
<artifactId>zebra-client</artifactId>
<version>2.9.2-SNAPSHOT</version>
</dependency>
<dependency>
<groupId>org.powermock</groupId>
<artifactId>powermock-api-mockito2</artifactId>
<version>2.0.2</version>
<scope>test</scope>
</dependency>
<dependencies>
- <groupId>,<artifactId>,<version>:依赖的基本坐标,Maven需要根据坐标才能找到依赖
- <type>(可选,默认为jar):依赖的类型,大多数情况下不必声明,默认为jar
- <scope>:依赖范围,见(3)
- <optional>:标记依赖是否可选,见(5)
- <exclusions>:排除传递性依赖,见(6)
(3)<scope>:依赖范围
- 概述:用来控制依赖与这三种classpath(编译,测试,运行)的关系,有以下几种选择
- compile(默认):在【编译,测试,运行】时都使用该依赖。比如spring-core(都需要用到)
- test:只对【测试】有效,在编译主代码或者运行项目时无法使用此类依赖。比如JUnit,mockito(只有在单元测试才用到这些依赖)
- provided:已提供该依赖。对于【编译和测试】有效。在运行时无效。
- runtime:对【测试和运行】有效,编译主代码时无效。典型的例子是JDBC驱动实现
- system:类似provided,但是provided可以通过本地maven仓库解析,system往往与本机系统绑定
- import:导入依赖范围,后面解释dependencyManagement时再介绍

?
(4)Maven的传递性依赖性质
- 何为依赖传递:【我的项目A】依赖【spring-core】,【spring-core】pom.xml中依赖【commons-logging】。则 【我的项目A】依赖【commons-logging】
- 依赖传递的范围:【我的项目A】依赖scope=test【spring-core】,【spring-core】依赖scope=compile【commons-logging】。则【我的项目A】依赖scope=test【commons-logging】
- 依赖的规则:第一原则优先,相同则采用第二原则
- 第一原则:依赖路径越短越优先。比如:A->B->C->X(1.0);A->D->X(2.0)。由于X(2.0)的路径短,X(2.0)会被解析使用
- 第二原则:看pom.xml中的依赖顺序,谁写在上面谁先依赖。比如A->B->Y(1.0);A->C->Y(2.0)。如果pom.xml文件中B写在C的上面,则Y(1.0)会被解析使用
(5)<optional>:可选依赖?
- 配置 <optional> true </optional> ,则该依赖为【可选依赖】
- 【可选依赖】有什么用:不具有传递性
- 比如:A->B,B->mysql.jar(可选),B->oracle.jar(可选)。
- 则依赖不会传递,即 A不会依赖mysql.jar和oracle.jar。换句话说:项目里没有mysql.jar和oracle.jar不会对A产生任何影响
- 为什么要【可选依赖】
- 假如项目B实现了两个特性,其中的特性一依赖于X,特性二依赖于Y,而且这两个特性是互斥的,用户不可能同时使用这两个特性
- 比如B是一个持久层隔离工具包,特性一用于mysql,特性二用于oracle,这两者是互斥的,究竟用哪个,让用户自己来手动选(手动引入)
- 例子:B的pom.xml(图一),用户如果要用mysql的jar包,需要在A中自己手动引(下图)
-
图一: ? ? -
图二: ?
(6)<exclusion>:排除依赖
- 假如项目里有个第三方依赖,该依赖还依赖了另一个1.0.0-SNAPSHOT版本的库,那么该1.0.0-SNAPSHOT就会成为当前项目的传递性依赖。此时我想排除该依赖,则要使用<exclusion>标签

?
- 需要注意的是:声明exclusion时候只需要groupId和artifactId,不需要version(显然,根据前两者就可以在pom.xml中唯一确定一个Maven坐标了)
(7)<properties>:归类依赖
- 假如项目里有很多Spring Framework的依赖(如下),你希望保持它们版本号一致,并且统一管理它们的版本
- org.springframework:spring-core:2.5.6
- org.springframework:spring-beans:2.5.6
- org.springframework:spring-context:2.5.6
- org.springframework:spring-context-support:2.5.6
- 使用<properties>标签
(8)优化依赖
- 可以通过命令查看项目中的所有依赖和依赖关系
- 显示所有已解析依赖:mvn dependency:list
- 查看解析后的依赖树:mvn dependency:tree
- 分析当前的项目依赖:mvn dependency:analyze
第六章:仓库
(1)Maven仓库和布局
- 何为仓库:Maven将所有【构建完成的jar包】安装部署到【Maven本地仓库】,防止浪费磁盘空间,并供各个项目调用
- Maven中【jar包路径】和【坐标】的关系:groupId/artifactId/version/artifactId-version.packaging,例子如下
 
(2)仓库的分类
- 只分为两类:【本地仓库】和【远程仓库】,一个用户只有一个【本地仓库】,但是可以配置多个【远程仓库】
- jar查找规则
- (1)先从【本地仓库】找
- (2)找不到再去【远程仓库】下载到【本地仓库】
- (3)如果都没有则报错
(3)本地仓库
- 默认配置下,【本地仓库】的路径为:用户目录/.m2/repository/...
- 比如Windows:C:\Users\jyy\.m2\repository\
- 如何更改【本地仓库】地址
- 将 $M2_HOME/conf/settings.xml 文件复制到 ~/.m2/settings.xml,并增加一行<localRepository> 标签配置。不过不推荐这个方式,因为不推荐修改全局目录的settings.xml文件

- 如何安装【本地Maven项目】到【本地仓库】
(3)远程仓库:【中央仓库】,【私服】,【其他公开的远程仓库】
- 【Maven中央仓库】:【Maven】自带的远程仓库,包含了绝大部分开源的构件:https://mvnrepository.com/
- Maven的安装文件自带【中央仓库】的配置,可以通过 $M2_HOME/lib/maven-model-builder-3.0.jar中的 org/apache/maven/model/pom-4.0.0.xml看到,该pom文件是一个超级POM,所有Maven项目都会继承
?
- 私服:架设在局域网内,代理外部广域网上的远程仓库
- ?jar包查询规则:先找【本地仓库】,再找【私服】,找不到再找【远程仓库】
- 为什么需要私服:
- 有些jar包是公司内部用的,不开源,可以放在私服
- 如果Internet不稳定,私服提高了稳定性
- 比较著名的有:Nexus
- 其他公开的远程仓库
- 常见的有 Java.net Maven库,JBoss Maven库
(4)如何配置【远程仓库】:在pom.xml中添加 <repositories> 标签
?
?
?
?
?
?
?
?
|