一、Maven概述
1.1、Maven概述
Maven是阿帕奇下的一个开源项目,它是一个项目管理工具,同时也是一个项目构建工具,它用于Java项目进行项目构建、依赖管理以及项目信息管理。
maven是通过pom.xml文件来管理项目,每个maven工程都有一个pom.xml文件
Maven包含了一个项目对象模型 (Project Object Model),一组标准集合,一个项目生命周期(Project Lifecycle),
一个依赖管理系统(Dependency Management System),和用来运行定义在生命周期阶段(phase)中插件(plugin)目标(goal)的逻辑。
maven有两个核心功能:项目构建、依赖管理(jar包管理)
依赖管理是将仓库中的依赖(jar包),添加到工程中。
项目构建是maven的声明周期来实现的,生命周期它包含一些阶段,这些阶段是有顺序的,每个阶段表示一个单独的功能,
每个阶段或者说每个功能是由一个个插件(plugin-in)来实现的。
maven是通过java开发的
maven仓库是存储依赖的,有两种类型,本地仓库和远程仓库.
本地仓库就是本地磁盘的目录。用于存储从远程仓库下载的插件和jar包,项目使用一些插件或jar包,优先从本地仓库查找。
依赖查找的优先级:从高到低 本地仓库 私服 远程仓库
SVN上未编译的文件,需要再进一步学习
1.2、Maven安装以及配置
1、下载
下载网址: http://maven.apache.org/download.cgi
本教程使用3.3.9 版本
2、解压不含有中文和空格的目录
bin目录 mvn.bat (以run方式运行项目)、 mvnDebug.bat(以debug方式运行项目 )
boot目录 maven运行需要类加载器
conf目录 settings.xml 整个maven工具核心配置文件
lib目录 maven运行依赖jar包
3、环境变量的配置
配置 MAVEN_HOME 为maven的解压根目录
配置环境变量path %MAVEN_HOME%/bin
通过在命令行中输入 mvn -v命令检查 配置是否成功
4、配置本地仓库
通过 MAVE_HOME/conf/settings.xml配置本地仓库位置:
<localRepository>F:\maven\repository3</localRepository>
1.3 m2e插件安装配置
使用最新版的eclipse mars,自带maven插件,不需要单独安装。
相应的maven插件设置图片
1.4 Maven仓库
使用maven需要配置仓库,仓库的作用就是管理依赖(jar包)。
Maven的仓库类型有两种:
1、本地仓库:
指的是本地磁盘目录,用来存储从远程仓库下载的插件和jar包,项目使用一些插件或jar包,优先从本地仓库查找。
注意:默认本地仓库位置在 ${user.dir}/.m2/repository,${user.dir}表示windows用户目录。我本机的用户目录:C:\Users\think
2、远程仓库:如果工程需要插件或者jar包,本地仓库没有,则去远程仓库下载。
a) 中央仓库
中央仓库地址:http://repo1.maven.org/maven2
它是由Maven自己维护,里面有大量的常用类库,并包含了世界上大部分流行的开源项目构件。
b) 私服
私服是搭建在公司内部的一个远程仓库,它可以管理公司内部的工程依赖及中央仓库的依赖。
依赖查找的优先级,从高到低:本地仓库--》私服--》中央仓库
二、Maven项目构建
使用maven来创建工程,使用maven来构建工程
2.1 maven来创建工程
maven工程是使用maven来管理java工程或者web工程。
maven工程主要分为两种java工程和web工程
maven工程创建有两种方式使用骨架,使用非骨架,使用骨架时需要进行联网
GAV坐标 用于定位依赖
Group Id 定义当前maven项目名称,为了和互联网上其它项目区别需要使用域名倒序
Aftifact Id 定义当前maven项目的模块名称
Version 项目版本 常用的版本类型包括:snapshot快照版 release 正式发布版
2.2 maven完整的目录结构
完整的目录结构如下:
src/main/java —— 存放项目的.java文件
src/main/resources —— 存放项目资源文件,如spring, hibernate配置文件
src/test/java —— 存放所有测试.java文件,如JUnit测试类
src/test/resources —— 测试资源文件
Maven dependenties —— maven工程依赖的jar
src/main —— web工程存储jsp、js等,相当于WebRoot
target ——编译输出目录
pom.xml ——每个maven工程都有一个pom.xml
2.3 设置编译版本,也即设置jdk版本
默认使用的是1.5版本
在pom.xml文件中,进行设置
<build>
<plugins>
<plugin>
<groupId>org.apache.maven.plugins</groupId>
<artifactId>maven-compiler-plugin</artifactId>
<configuration>
<source>1.7</source>
<target>1.7</target>
<encoding>UTF-8</encoding>
</configuration>
</plugin>
</plugins>
</build>
配置完pom.xml文件后需要执行update project操作
2.4 maven命令
Run as 采用 mvn 命令运行 ,Debug as 采用 mvnDebug 命令调试方式运行(可打断点)
mvn clean 清理target目录
清除target目录 (清除所有编译结果或者打包结果 ),清理后编译。
mvn compile 编译源码命令
编译后.class文件在target/classes下 这个命令只会对java源程序进行编译
mvn test-compile 编译测试类命令
编译后.class文件在target/test-classes下 这个命令只会对java源程序进行编译
mvn test 执行单元测试
执行所有测试用例方法,重新编译
mvn install将工程打包后发布到本地仓库
安装命令 mvn install 将工程打包后发布到本地仓库
---- 安装到仓库/groupId/artifactId/version 目录下
mvn package
java项目生成 jar包, web项目生成war包
默认生成jar包名称 : artifactId-version.jar
java项目生成 jar包, web项目生成war包
默认生成jar包名称 : artifactId-version.jar
mvn deploy 部署命令,会将打成的jar包或者war包安装到私服中
Maven build 使用之前操作过的命令
Maven build … 手动输入命令内容
组合命令
可以将maven命令进行组合使用,但是注意只能是clean和其他命令组合。
2.5 pom.xml的基本配置
pom.xml是Maven项目的核心配置文件,位于每个工程的根目录,基本配置如下:
<project > :文件的根节点 . <modelversion > : pom.xml使用的对象模型版本
<groupId > :公司名称,一般写公司的域名
<artifactId > :项目名称
<version > :产品的版本号 .
<packaging > :打包类型,一般有jar、war、pom 等
<name > :项目的显示名,常用于 Maven 生成的文档。
<description > :项目描述,常用于 Maven 生成的文档
<dependencies> :项目依赖构件配置,配置项目依赖构件的坐标
<build> :项目构建配置,配置编译、运行插件等。
2.6 pom.xml的详细配置
POM即项目对象模型 (Project Object Model),在POM中定义项目依赖的坐标、项目信息、项目构建等配置,
一个pom.xml文件定义了一个Maven项目。
第一部分: POM Relationships 关系
Coordinates 坐标: 在仓库中唯一标识项目位置三个参数
<groupId> 项目名称
<artifactId> 模块名称
<version> 版本号
Aggregation 聚合(多模块) : 将项目分解为多个不同模块
Inheritance 继承 : 项目之间继承,实现POM复用
Dependencies 依赖: 项目依赖另一个项目进行编译或者运行
第二部分: Project Information 项目信息
name :项目名称
desciption: 项目描述
第三部分: Build settings 构建配置
properties : 配置属性
build :构建项目需要插件配置
packaging :打包方式 jar、war、pom
reporting : 报表
第四部分: Build Environment 构建环境 (在依赖、构建、运行 生效配置 )
DependenciesManagement :版本锁定
Profile : 灵活自定义配置,在特定情况激活
dependency 引入依赖
2.7 Maven的生命周期
Maven的项目构建都是提高生命周期来实现的。
Maven本身包含三个生命周期:
Clean生命周期:清除上次构建的文件
Default生命周期:主要包含构建过程中的编译、测试、打包、部署到功能。
Site生命周期:生成站点
每个生命周期都是由一些阶段组成,这些阶段是 有顺序的,执行后面的命令,则会把前面的命令,按照顺序进行执行。
1、 Clean生命周期
pre-clean 执行一些需要在clean之前完成的工作
clean 移除所有上一次构建生成的文件
post-clean 执行一些需要在clean之后立刻完成的工作
2、 Default生命周期(重点)
Maven的主要生命周期
validate
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 接受编译好的代码,打包成可发布的格式,如 JAR 。
pre-integration-test
integration-test
post-integration-test
verify
install 将包安装至本地仓库,以让其它项目依赖。
deploy 将最终的包复制到远程的仓库,以让其它开发人员与项目共享。
3、 Site生命周期
pre-site 执行一些需要在生成站点文档之前完成的工作
site 生成项目的站点文档
post-site 执行一些需要在生成站点文档之后完成的工作,并且为部署做准备
site-deploy 将生成的站点文档部署到特定的服务器上
三、Maven依赖管理
3.1 添加依赖
获取坐标的方式:
1、从互联网搜索
http://search.maven.org/
http://mvnrepository.com/
2、使用Maven的插件索引功能
Maven - addDependecy
1、通过坐标导入依赖
!-- 引入junit -->
<dependency>
<groupId>junit</groupId>
<artifactId>junit</artifactId>
<version>4.10</version>
</dependency>
<!-- 第一直接依赖,引入maven项目 -->
<dependency>
<groupId>cn.lx</groupId>
<artifactId>mavenweb5</artifactId>
<version>0.0.1-SNAPSHOT</version>
</dependency>
3.2 依赖范围
即项目中的jar包所能影响的范围,其中范围指的是:main目录、test目录、war包。
默认的依赖范围就是compile。
其中依赖范围scope 用来控制依赖和编译,测试,运行的classpath的关系. 主要的是三种依赖关系如下:
1.compile: 默认编译依赖范围。对于编译,测试,运行三种classpath都有效
2.test:测试依赖范围。只对于测试classpath有效
3.provided:已提供依赖范围。对于编译,测试的classpath都有效,但对于运行无效。因为由容器已经提供,例如servlet-api
4.runtime:运行时提供。例如:jdbc驱动
只需要关注provided依赖范围就可以。
依赖范围由强到弱的顺序是:compile>provided>runtime>test
3.3 依赖传递
A 依赖B、B依赖C,则A中自动导入C。C是A的传递依赖,如果C依赖D则D也是A的传递依赖。
其中B是A的直接依赖,C是A的传递依赖。
依赖会有依赖范围,依赖范围对传递依赖也有影响,有A、B、C三个过程,A依赖B、B依赖C,C可能是A的传递依赖,如下图:
最左边一列为直接依赖,理解为A依赖B的范围,最顶层一行为传递依赖,理解为B依赖C的范围,行与列的交叉即为A传递依赖C的范围。
举例:
比如 A对 B 有 compile 依赖,B 对C有 runtime 依赖,那么根据表格所示A对C 有 runtime 依赖。
总结:
每个单元格都对应行列中最弱的那个,当 p1 依赖 p2,p2 依赖 p3……,最终,p1 传递依赖了pn 的时候,p1 对 pn 的依赖性取决于依赖链中最弱的一环。
3.4 依赖版本冲突解决
1、问题
当一个项目依赖的构件比较多时,它们相互之间存在依赖,当你需要对依赖版本统一管理时如果让maven自动来处理可能并不能如你所愿。
例如:struts2-spring-plugin依赖spirng-beans-3.0.5,spring-context依赖spring-beans-4.2.4,但是发现spirng-beans-3.0.5加入到工程中,
而我们希望spring-beans-4.2.4加入工程。
2、依赖调解原则
Maven自动按照下边的原则进行调解
第一原则:路径近者优先原则
例如:A-> spirng-beans-4.2.4,A->B-> spirng-beans-3.0.5,则spirng-beans-4.2.4优先
第二原则:第一声明者优先原则
如果路径一致,则按照第二原则进行依赖调解。
在pom文件中谁先声明以谁为准。
如果将上边struts-spring-plugins和spring-context顺序颠倒,系统将导入spring-beans-4.2.4。
第三原则:排除依赖
可以通过排除依赖方法辅助依赖调解:
比如struts2-spring-plugin中添加排除spring-beans:
<!-- struts2-spring-plugin依赖spirng-beans-3.0.5 -->
<dependency>
<groupId>org.apache.struts</groupId>
<artifactId>struts2-spring-plugin</artifactId>
<version>2.3.24</version>
<!-- 排除 spring-beans-->
<exclusions>
<exclusion>
<groupId>org.springframework</groupId>
<artifactId>spring-beans</artifactId>
</exclusion>
</exclusions>
</dependency>
则最终的依赖版本为4.2.4.
第四原则:锁定版本(推荐使用)
面对众多的依赖,有一种方法不用考虑依赖路径、声明优化等因素可以采用直接锁定版本的方法确定依赖构件的版本,此方法在企业开发中常用:
使用dependencyManagement标签来进行锁定版本。
dependencyManagement标签只是对版本进行锁定,没有进行真实依赖
<dependencyManagement>
<dependencies>
<!--这里锁定版本为4.2.4 -->
<dependency>
<groupId>org.springframework</groupId>
<artifactId>spring-beans</artifactId>
<version>4.2.4.RELEASE</version>
</dependency>
</dependencies>
</dependencyManagement>