Maven
什么是Maven
Maven是一款服务于Java平台自动化构建工具。
自动化构建工具发展趋势:make->Ant->Maven->Gradle
参考:
博客园-QiaoZhi:Maven的默认中央仓库以及修改默认仓库&配置第三方jar包从私服下载
配置国内源
首先要想在国内顺利的使用Maven,我们首先要进行一些配置,才可以进行各种Maven所需Jar包的下载,当然无论是IDEA自带的Maven或者是自己替换一个Maven(不建议这么做),但始终都有一个问题就是在国内因为wall封锁,导致自己写入POM配置不能很快的更新jar,我们首先要做的就是解决这个问题:
找到自己intellij-idea的存储路径,我的Arch Linux上的路径为:
/opt/intellij-idea-ultimate-edition/plugins/maven/lib/maven3/conf/settings.xml
修改这个文件找到
<mirrors></mirrors>
标签。将以下内容写入这个标签之间:
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23<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>mirrorId</id>
<mirrorOf>repositoryId</mirrorOf>
<name>Human Readable Name for this Mirror.</name>
<url>http://my.repository.com/repo/path</url>
</mirror>
-->
<mirror>
<id>aliyunmaven</id>
<mirrorOf>apache snapshots</mirrorOf>
<name>aliyun apache</name>
<url>https://maven.aliyun.com/repository/apache-snapshots</url>
</mirror>
</mirrors>
当然IDEA启动时候就会自动加载这个配置文件,重新启动IDEA即可发现配置加载速度比之前快了好多,此时已经不用去Maven官网中心仓库去下载,而是从国内源下载。
经过测试发现
当我配置一个带有本地jar(不能从外网获取)依赖的项目时,填多个mirror
只能访问其中的一个,除非mirror
不能访问,才会自动访问另一个。
建议了解一下Nexus。
Java项目的构建
把在动态web项目工程经过编译后得到的编译结果部署到服务器上的整个过程。
编译:Java源文件(.java)经过编译成为class字节码文件(.class)
部署:将编译后的动态web项目导入到服务器中上线。
构建的各个环节:
- 清理clean:将以前编译得到的旧文件class字节码文件删除
- 编译compile:将java源程序编译成class字节码文件
- 测试test:自动测试,自动调用junit程序
- 报告report:测试程序执行的结果
- 打包package:动态Web工程打War包,java工程打jar包
- 安装install:Maven特定的概念—–将打包得到的文件复制到“仓库”中的指定位置
- 部署deploy:将动态Web工程生成的war包复制到Servlet容器下,使其可以运行
为什么使用Maven
以前的方式 | 现在的方式 |
---|---|
一个项目之间进行相互依赖比较麻烦 | 借助Maven可以将一个项目拆分成多个工程(比如之前的项目拿来多当前项目的依赖调用其中的方法) |
项目之间的Jar包需要复制粘贴 | 借助于Maven直接将jar包保存在“仓库”中,直接导入到POM配置文件中即可 |
项目jar包需要去官网下载 | Maven中的项目直接写入配置文件POM中 |
jar包之间不一致的风险 | Maven直接调库中唯一名称唯一版本标识的唯一jar包文件即可 |
jar包依赖jar包需要手动导入 | Maven直接继承下之前jar包所需的依赖 |
安装Maven
ArchLinux下安装
1 | pacman -S maven |
完成后在/opt/maven目录接可使用IDEA导入即可使用。
验证:
1 | maven -v #查看Maven版本信息 |
本地仓库存于:
- Windows
C:\<User Name>/.m2/repository
- Linux
~/.m2/repository
第一个Maven
根目录:工程名
|—src:源码
|—|—main:存放主程序
|—|—|—java:java源码文件
|—|—|—resource:存放框架的配置文件
|—|—test:存放测试程序
|—pom.xml:maven的核心配置文件(Project Object Model 项目对象模型)
使用IDE直接可以自动创建这些文件夹以及必要maven所需文件,当热为了方便理解还是手动创建比较好。
初始化pom.xml文件以及内容直接可被IDeA生成。
常用的maven命令:
以下 的命令必须在含有pom.xml的目录中执行。
命令 | 描述 |
---|---|
mvn clean | 清理 |
mvn compile | 编译主程序 |
mvn test-compile | 编译测试程序 |
mvn test | 执行测试 |
mvn package | 打包 |
mvn install | 安装 |
- 执行
mvn compile
表示即编译又进行依赖的处理,编译完成后Maven的目录会多出一个target目录(IDEA也是一样的)。 - 执行
mvn test-compile
target 目录下会多出一个test-classes文件夹 mvn package
,target文件夹下面又多了一个打好的jar包(将当前项目打包成jar文件)。mvn clear
清空整个编译后的任何文件。
Maven专业名词
坐标
pom.xml:Project Object Model 项目对象模型。它是maven的核心配置文件,所有的构建的配置都在这里设置。
坐标:使用三个向量在仓库中唯一的定位一个maven工程
1 | <dependencies> |
maven坐标和仓库对应的映射关系:
- 处理 groupId,每一个 . 转化为一级文件夹。比如‘org.springframework’,就是首先在repository 文件夹下创建一个 org 文件夹(已有的话不用创建),然后在 org 文件夹下创建 springframework 文件夹;
- 再下一级创建以 artifactId 命名的文件夹,即在 springframework 文件夹下创建 spring-core 文件夹;
- 创建版本号文件夹;
- 把 artifactId 和 version 用连字符连接(如果有 classifier 也要连接),然后加上扩展名,就是实际文件的地址。
仓库
本地仓库:
自己本机电脑上的仓库。
远程仓库:
- 私服:搭建在局域网中,一般公司都会有私服,私服一般使用nexus来搭建。
- 中央仓库:架设在Internet上,像刚才的springframework就是在中央仓库上。
依赖
- maven解析依赖信息首先会去中央仓库查找被依赖的jar包。
- 对于本地仓库中没有的回去中央仓库查找,查到之后下载到本地。
- 如果依赖是自己或者团队开发项目,先在被依赖项目使用install把被依赖的maven工程的jar包导入到本地仓库。
依赖范围
scope标签就是依赖的范围:
compile默认值,适用于所有阶段(开发、测试、部署、运行),本jar会一直存在所有阶段。
provided只在开发、测试阶段使用,目的是不让Servlet容器和你本地仓库的jar包冲突 。如servlet.jar。
runtime只在运行时使用,如JDBC驱动,适用运行和测试阶段。
test只在测试时使用,用于编译和运行测试代码。不会随项目发布。
system类似provided,需要显式提供包含依赖的jar,Maven不会在Repository中查找它。
生命周期
maven 有三套互相独立的生命周期,分别是:Clean Lifecycle、Default Lifecycle、Site Lifecycle。
Clean Lifecycle 在进行真正的构建之前进行一些清理工作。
- pre-clean 执行一些需要在clean之前完成的工作
- clean 移除所有上一次构建生成的文件
- post-clean 执行一些需要在clean之后立刻完成的工作
Default Lifecycle构建的核心部分,编译,测试,打包,部署等等。
不论你要执行生命周期的哪一个阶段,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 将最终的包复制到远程的仓库,以让其它开发人员与项目共享
Site Lifecycle 生成项目报告,站点,发布站点。
- pre-site 执行一些需要在生成站点文档之前完成的工作
- site 生成项目的站点文档
- post-site 执行一些需要在生成站点文档之后完成的工作,并且为部署做准备
- site-deploy 将生成的站点文档部署到特定的服务器上
maven工程的依赖高级特性
依赖与被依赖间处理
WebMavenDemo(子)项目依赖JavaMavenService1 JavaMavenService1(父)项目依赖JavaMavenService2(曾祖父)。
pom.xml文件配置好依赖关系,必须首先mvn install后,依赖的jar包才能使用,即:
WebMavenDemo的pom.xml文件想能编译通过,JavaMavenService1必须
mvn install
JavaMavenService的pom.xml文件想能编译通过,JavaMavenService2必须
mvn install
依赖间属性
依赖传递性
为JavaMavenService2(曾祖父)中增加了一个spring-core.jar包后,会惊喜的发现依赖的两个项目(父 子)都自动的增加了这个jar包,这就是依赖的传递性。注意:非compile范围的依赖是不能传递的
路径最短者优先
JavaMavenService2(曾祖父)中解除旧版Log4j 1.2.7.jar,自己添加一个新版Log4j 1.2.9.jar,此版本只会影响自己及后代(父 子),不会影响前辈(曾祖父)。
统一管理依赖的版本
为了统一管理版本号,可以使用properties标签,里面可以自定义版本的标签名。在使用的地方使用${自定义标签名}。
build配置
1 | <build> |
执行mvn package
之后,在maven工程指定的target目录里war包和文件都按照配置的生成了: