文章目录
Maven核心概念
统一管理目标jar包的版本
以对Spring的jar包依赖为例:Spring的每一个版本中都包含spring-context,springmvc等jar包。我们应该导入版本一致的Spring jar包,而不是使用4.0.0的spring-context的同时使用4.1.1的springmvc。
javascript
<dependency>
<groupId>org.springframework</groupId>
<artifactId>spring-context</artifactId>
<version>4.0.0.RELEASE</version>
</dependency>
<dependency>
<groupId>org.springframework</groupId>
<artifactId>spring-webmvc</artifactId>
<version>4.0.0.RELEASE</version>
</dependency>
<dependency>
<groupId>org.springframework</groupId>
<artifactId>spring-jdbc</artifactId>
<version>4.0.0.RELEASE</version>
</dependency>
<dependency>
<groupId>org.springframework</groupId>
<artifactId>spring-orm</artifactId>
<version>4.0.0.R
问题是如果我们想要将这些jar包的版本统一升级为4.1.1,是不是要手动一个个修改呢?显然,我们有统一配置的方式:
javascript
<!--统一管理当前模块的jar包的版本-->
<properties>
<spring.version>4.0.0.RELEASE</spring.version>
</properties>
......
<dependency>
<groupId>org.springframework</groupId>
<artifactId>spring-context</artifactId>
<version>${spring.version}</version>
</dependency>
<dependency>
<groupId>org.springframework</groupId>
<artifactId>spring-webmvc</artifactId>
<version>${spring.version}</version>
</dependency>
<dependency>
<groupId>org.springframework</groupId>
<artifactId>spring-jdbc</artifactId>
<version>${spring.version}</version>
</dependency>
<dependency>
<groupId>org.springframework</groupId>
<artifactId>spring-orm</artifactId>
<version>${spring.version}</version>
</dependency>
这样一来,进行版本调整的时候只改一改地方就行了
仓库
1)分类
(1)本地仓库:为当前本机电脑上的所有Maven工程服务。
(2)远程仓库
①私服:架设在当前局域网环境下,为当前局域网范围内的所有Maven工程服务。
②中央仓库:架设在Internet上,为全世界所有Maven工程服务。
③中央仓库的镜像:架设在各个大洲,为中央仓库分担流量。减轻中央仓库的压力,同时更快的响应用户请求。
2)仓库中的文件
(1)Maven的插件
(2)我们自己开发的项目的模块
(3)第三方框架或工具的jar包
不管是什么样的jar包,在仓库中都是按照坐标生成目录结构,所以可以通过统一的方式查询或依赖。
生命周期
1)什么是Maven的生命周期?
Maven生命周期定义了各个构建环节的执行顺序,有了这个清单,Maven就可以自动化的执行构建命令了。
Maven有三套相互独立的生命周期,分别是:
a.Clean Lifecycle在进行真正的构建之前进行一些清理工作。
b.Default Lifecycle构建的核心部分,编译,测试,打包,安装,部署等等。
c.Site Lifecycle生成项目报告,站点,发布站点。
再次强调一下它们是相互独立的,你可以仅仅调用clean来清理工作目录,仅仅调用site来生成站点。当然你也可以直接运行mvn clean install site运行所有这三套生命周期。
每套生命周期都由一组阶段(Phase)组成,我们平时在命令行输入的命令总会对应于一个特定的阶段。比如,运行mvn clean,这个clean是Clean生命周期的一个阶段。有Clean生命周期,也有clean阶段。
2)clean生命周期
Clean生命周期一共包含了三个阶段:
a.pre-clean 执行一些需要在clean之前完成的工作
b.clean 移除所有上一次构建生成的文件
c.post-clean 执行一些需要在clean之后立刻完成的工作
3)Site生命周期
a.pre-site执行一些需要在生成站点文档之前完成的工作
b.site生成项目的站点文档
c.post-site执行一些需要在生成站点文档之后完成的工作,并且为部署做准备
d.site-deploy将生成的站点文档部署到特定的服务器上
这里经常用到的是site阶段和site-deploy阶段,用以生成和发布Maven站点,这可是Maven相当强大的功能,Manager比较喜欢,文档及统计数据自动生成,很好看。
4)Default生命周期
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将最终的包复制到远程的仓库,以让其它开发人员与项目共享或部署到服务器上运行。
5)生命周期与自动化构建
运行任何一个阶段的时候,它前面的所有阶段都会被运行,例如我们运行mvn install 的时候,代码会被编译,测试,打包。这就是Maven为什么能够自动执行构建过程的各个环节的原因。此外,Maven的插件机制是完全依赖Maven的生命周期的,因此理解生命周期至关重要。
插件和目标
(1)Maven的核心仅仅定义了抽象的生命周期,具体的任务都是交由插件完成的。
(2)每个插件都能实现多个功能,每个功能就是一个插件目标。
(3)Maven的生命周期与插件目标相互绑定,以完成某个具体的构建任务。
例如:compile就是插件maven-compiler-plugin的一个功能;pre-clean是插件maven-clean-plugin的一个目标。
继承
为什么需要继承机制
由于非compile范围的依赖信息是不能在"依赖链"中传递的,所以有需要的工程只能单独配置。例如:
此时如果项目需要将各个模块的junit版本统一为4.9,那么到各个工程中手动修改无疑是非常不可取的。使用继承机制就可以将这样的依赖信息统一提取到父工程模块中进行统一管理
创建父工程
(1)父工程的打包方式为pom
javascript
<groupId>com.atguigu.maven</groupId>
<artifactId>Parent</artifactId>
<packaging>pom</packaging>
<version>1.0-SNAPSHOT</version>
(2)父工程只需要保留pom.xml文件即可。
在子工程中引用父工程
在子工程中引用父工程
(1)父工程坐标
javascript
<parent>
<!-- 父工程坐标 -->
<groupId>...</groupId>
<artifactId>...</artifactId>
<version>...</version>
<!--指定从当前pom.xml文件出发寻找父工程的pom.xml文件的相对路径-->
<relativePath>..</relativePath>
</parent>
(2)继承
javascript
<!--继承-->
<parent>
<groupId>com.atguigu.maven</groupId>
<artifactId>Parent</artifactId>
<version>1.0-SNAPSHOT</version>
<!--指定从当前pom.xml文件出发寻找父工程的pom.xml文件的相对路径-->
<relativePath>../Parent/pom.xml</relativePath>
</parent>
此时,如果子工程的groupId和version如果和父工程重复则可以删除。
在父工程中管理依赖
(1)将Parent项目中的dependencies标签,用dependencyManagement标签括起来。
javascript
<!--依赖管理-->
<dependencyManagement>
<dependencies>
<dependency>
<groupId>junit</groupId>
<artifactId>junit</artifactId>
<version>4.0</version>
<scope>test</scope>
</dependency>
</dependencies>
</dependencyManagement>
(2)在子项目中重新指定需要的依赖,删除范围和版本号。
javascript
<dependency>
<groupId>junit</groupId>
<artifactId>junit</artifactId>
</dependency>
聚合
为什么要使用聚合
将多个工程拆分为模块后,需要手动逐个安装到仓库后依赖才能够生效。修改源码后也需要逐个手动进行clean操作。而使用了聚合之后就可以批量进行Maven工程的安装、清理工作。
如何配置聚合
在总的聚合工程中使用modules/module标签组合,指定模块工程的相对路径即可。
javascript
<!--聚合-->
<modules>
<module>../MakeFriend</module>
<module>../OurFriends</module>
<module>../HelloFriend</module>
<module>../Hello</module>
</modules>
Maven可以根据各个模块的继承和依赖关系自动选择安装的顺序。
Maven酷站
我们可以到http://mvnrepository.com/搜索需要的jar包的依赖信息。
Maven生产环境所遇到的问题
jar未下载完成
在使用maven过程中,我们所使用的jar包是会到中央仓库中进行下载的,但是如果再下载过程中因为网络不通畅等原因,会导致jar包下载失败,并且会形成一个xxxx.lastupdated的文件,但是此时maven并不会将其删掉后重新下载,而是认为它下载过了,我们需要做的是将.xxxxlastupdated文件手动删除后,再次重新下载。
javascript
<dependency>
<groupId>junit</groupId>
<artifactId>junit</artifactId>
<version>4.0</version>
<scope>test</scope>
</dependency>
1)问题模拟
(1)在项目导入了maven依赖,在仓库中发现目前没有这个依赖。
(2)此刻电脑没有网络
(3)点击maven的刷新后,maven会去下载,但是下载不下来。
(4)最终在本地仓库会形成一下模样。
(5)并且连接上网络后并不会继续下载,形成如下模样。
2)解决方案1
手动删除.lastupdate文件,让其重新下载就好了。
3)解决方案2
直接在仓库下搜索.lastupdated文件,然后ctrl+a全选后ctrl+d删除 就能直接删掉所有没下载号的jar包。
jar包冲突问题
jar包冲突往往是发生在,同一个项目在运行时导入了两个相同jar包的不同版本,又因为两个不同版本的jar包代码是不一样的,是冲突的,导致在运行时,报出各种莫名其妙的错误。
1)问题描述
以上依赖中,thymeleaf-spring5--3.0.12是天然依赖于thymeleaf的3.0.12版本的依赖的,但是因为我们自己的导入是thymeleaf 3.0.11版本,这两个版本代码差距巨大,就会导致jar包冲突问题。
2)解决方案
要么不要导入3.0.11版本依赖,或者你选在将thymeleaf-spring5--3.0.12的依赖中的thymeleaf的3.0.12
版本排除掉(图解是排除的方式)。