参考教程 :
跟着刚哥深入学maven(通俗易懂)
Maven学习总结
Maven通俗讲解
1.1 why we need this?
第一次听到Maven的时候,自然就去查了下,结果大都就是说管理依赖blahblah的,其实作为学生,所接触过的项目也就仅限于几百行代码的小工具啊,我又不是大公司,自己怎么写出来一个还需要外部jar包依赖之类的大项目,所以也就一直对这个项目依赖管理这方面不是很care。
直到后来自己写的代码也多了一些,确实管理起来也有点混乱,再来接触到maven这个东西,就理解了这个东西存在的价值。
[一个简单的问题]
在进行讲解前,先提问一个简单的问题。
假如你正在Eclipse下开发两个Java项目,姑且把它们称为A、B,其中A项目中的一些功能依赖于B项目中的某些类,那么如何维系这种依赖关系的呢?
在使用Maven前是这样做的,将B项目打包为jar,并在A项目的Library下导入B的jar文件。
这样做有着很明显的缺点:
- 如果在开发过程中,发现B中的bug,则必须重新将B打包并对A项目进行重编译操作
- 在协同开发A项目时,为了保证其能够正常运行,要么选择将B打包入A中,要么选择将B一样发布出去并告知开发者使用方法。
- 显然这两个方法都不太好,前者可能造成资源浪费(比如开发者可能正在开发依赖B的其它项目,B已经存储到本地了),而后者则会为项目正常运行带来风险(一旦把工作交给人工注定会带来一定的失败率)。显然这两个方法都不太好,前者可能造成资源浪费(比如开发者可能正在开发依赖B的其它项目,B已经存储到本地了),而后者则会为项目正常运行带来风险(一旦把工作交给人工注定会带来一定的失败率)。
因此,这样手动的控制项目间依赖关系显然是一种‘拙劣’的方法。
① 一个项目就是一个工程
如果项目非常庞大,就不适合使用package来划分模块,最好是每一个模块对应一个工程,利于分工协作。
借助于maven就可以将一个项目拆分成多个工程
② 项目中使用jar包,需要“复制”、“粘贴”项目的lib中
同样的jar包重复的出现在不同的项目工程中,你需要做不停的复制粘贴的重复工作。
借助于maven,可以将jar包保存在“仓库”中,不管在哪个项目只要使用引用即可就行。
③ jar包需要的时候每次都要自己准备好或到官网下载
借助于maven我们可以使用统一的规范方式下载jar包,规范
④ jar包版本不一致的风险
不同的项目在使用jar包的时候,有可能会导致各个项目的jar包版本不一致,导致未执行错误。
借助于maven,所有的jar包都放在“仓库”中,所有的项目都使用仓库的一份jar包。
⑤ 一个jar包依赖其他的jar包需要自己手动的加入到项目中
极大的浪费了我们导入包的时间成本,也极大的增加了学习成本。
借助于maven,它会自动的将依赖的jar包导入进来。
所以
- 帮你以正确的方式,下载正确的jar包;
- 帮你寻找依赖,下载依赖
- 热部署,热编译
1.2 安装和测试
这部分就不多讲了。
这里有个关于修改从Maven中心仓库下载到本地的jar包的默认存储位置,
从Maven中心仓库下载到本地的jar包的默认存放在” u s e r . h o m e / . m 2 / r e p o s i t o r y ” 中 , {user.home}/.m2/repository”中, user.home/.m2/repository”中,{user.home}表示当前登录系统的用户目录(如"C:\Users\xiaozhou")。
.m2应该是Windows下的隐藏目录,没找到的同学先打开自己的隐藏目录
Jar包存放在这个位置不太好,我们希望能够自己定义下载下来的jar包的存放位置,因此我们可以自己设置下载到本地时的jar包的存放目录。
找到apache-maven-3.2.3\conf目录下的settings.xml
文件,加上一句代码:
<localRepository>E:/repository</localRepository>
如下图所示:
1.3 what is maven?
maven是一款服务于java平台的自动化构建工具
make->Ant->Maven->Gradle
1.3.1 目录组成
Maven的核心功能便是合理叙述项目间的依赖关系。
所有的Maven项目包含着一个名为pom.xml的文件,在文件中记录着自己的<groupId><artifactId><version>
等字段,这些字段在创建Maven项目时填写,Maven会依据它们来定位到该项目。
在pom中的另一个关键标签是<dependencies>
,该标签下可以包含若干个<dependency>
标签,而<dependency>下则是上面介绍的<groupId><artifactId><version>
等依赖字段。
它们确定着一个唯一的项目版本。
注:执行maven命令必须进入到pom.xml的目录中进行执行,即maven project的根目录。
1.3.2 一个典型的pom.xml
:
<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>org.keplerproject</groupId>
<artifactId>luajava</artifactId>
<version>1.1</version>
<packaging>jar</packaging>
<name>luajava</name>
<url>http://maven.apache.org</url>
<properties>
<project.build.sourceEncoding>UTF-8</project.build.sourceEncoding>
</properties>
<build>
<plugins>
<plugin>
<groupId>org.apache.maven.plugins</groupId>
<artifactId>maven-compiler-plugin</artifactId>
<version>2.0.2</version>
<configuration>
<source>1.7</source>
<target>1.7</target>
</configuration>
</plugin>
</plugins>
</build>
<dependencies>
<dependency>
<groupId>junit</groupId>
<artifactId>junit</artifactId>
<version>3.8.1</version>
<scope>test</scope>
</dependency>
</dependencies>
</project>
pom.xml文件的节点元素说明:
<project> | pom文件的顶级节点 |
<modelVersion> | object model版本,对Maven2和Maven3来说,只能是4.0.0 |
<groupId> | 项目创建组织的标识符,一般是域名的倒写 |
<artifactId> | 定义了项目在所属组织的标识符下的唯一标识,一个组织下可以有多个项目 |
<version> | 当前项目的版本,SNAPSHOT,表示是快照版本,在开发中 |
<packaging> | 打包的方式,有jar、war、ear等 |
<name> | 项目的名称 |
<url> | 项目的地址 |
<properties> | 属性配置,比如:<project.build.sourceEncoding>UTF-8</project.build.sourceEncoding> |
<dependencies> | 构建项目依赖的jar |
1.4 仓库和坐标
-
仓库的分类:
- 1、本地仓库:当前电脑上的仓库,上面修改的仓库就是本地仓库;
- 2、远程仓库:
- (1)私服:搭建在局域网中,一般公司都会有私服,私服一般使用nexus来搭建。具体搭建过程可以查询其他资料;
- (2)中央仓库:架设在Internet上,像刚才的springframework就是在中央仓库上。
解析依赖时,先在本地仓库中查找被依赖的jar包,再去中央仓库,若都无,则编译失败。
maven坐标和仓库对应的映射关系:[groupId ]\ [artifactId] \ [version] \ [artifactId]-[version].jar
去本地仓库看一下此目录:org\springframework\spring-core\4.3.4.RELEASE\spring-core-4.3.4.RELEASE.jar
果然是完全对应的(默认仓库地址上面说过了)
依赖范围
上面除了定位jar包的三个坐标以外,还有一个<scope>
,就是字面的意思,此依赖所作用的范围(环节),默认是compile(下面会讲到maven的各个环节),当然可以选择其他:
1、compile | 默认值,适用于所有阶段(开发、测试、部署、运行),本jar会一直存在所有阶段。 |
2、provided | 只在开发、测试阶段使用,目的是不让Servlet容器和你本地仓库的jar包冲突 。如servlet.jar。 |
3、runtime | 只在运行时使用,如JDBC驱动,适用运行和测试阶段。 |
4、test | 只在测试时使用,用于编译和运行测试代码。不会随项目发布。 |
5、system | 类似provided,需要显式提供包含依赖的jar,Maven不会在Repository中查找它。 |
1.5 各个环节
[1] 清理clean | 将以前编译得到的旧文件class字节码文件删除 |
[2] 编译compile | 将java源程序编译成class字节码文件 |
[3] 测试test | 自动测试,自动调用junit程序 |
[4] 报告report | 测试程序执行的结果 |
[5] 打包package | 动态Web工程打War包,java工程打jar包 |
[6] 安装install | Maven特定的概念-----将打包得到的文件复制到“仓库”中的指定位置 |
[7] 部署deploy | 将动态Web工程生成的war包复制到Servlet容器下,使其可以运行 |
关于各个环节的练习也可以看这个参考教程 Maven学习总结(一)——Maven入门。
1.6 生命周期
Maven有三套相互独立的生命周期
-
Clean Lifecycle 在进行真正的构建之前进行一些清理工作。Clean生命周期一共包含了三个阶段:
1、pre-clean 执行一些需要在clean之前完成的工作
2、clean 移除所有上一次构建生成的文件
3、post-clean 执行一些需要在clean之后立刻完成的工作 -
Default Lifecycle 构建的核心部分,编译,测试,打包,部署等等。
1、validate
2、generate-sources
3、process-sources
4、generate-resources
5、process-resources 复制并处理资源文件,至目标目录,准备打包
6、compile 编译项目的源代码
7、process-classes
8、generate-test-sources
9、process-test-sources
10、generate-test-resources
11、process-test-resources 复制并处理资源文件,至目标测试目录
12、test-compile 编译测试源代码
13、process-test-classes
14、test 使用合适的单元测试框架运行测试。这些测试代码不会被打包或部署
15、prepare-package
16、package 接受编译好的代码,打包成可发布的格式,如 JAR
17、pre-integration-test
18、integration-test
19、post-integration-test
20、verify
21、install 将包安装至本地仓库,以让其它项目依赖。
22、deploy 将最终的包复制到远程的仓库,以让其它开发人员与项目共享 -
Site Lifecycle 生成项目报告,站点,发布站点。
1、pre-site 执行一些需要在生成站点文档之前完成的工作
2、site 生成项目的站点文档
3、post-site 执行一些需要在生成站点文档之后完成的工作,并且为部署做准备
4、site-deploy 将生成的站点文档部署到特定的服务器上
1.x 后记
一圈下来,个人理解大概就是在pom.xml这个配置文件中,来加载本项目所需要依赖的各种唯一jar包(包-模块-版本),并且这些jar包是可以动态编译部署的,就不用每次都手动重新部署了。