1. 初衷
相信每个java开发人员对maven都不陌生,它和git,svn,idea一样,伴随着我们开发的每一分钟。
但你在大多数时候,只是在使用它,你真的认识它,了解它,熟悉它吗?
今天我来分享一点,我在项目中使用maven总结出的东西
2. 仓库
仓库,是用来存放东西的地方,maven仓库也是一样,用来存放我们会用到的一些构件
Maven 仓库能帮助我们管理构件(主要是JAR),它就是放置所有JAR文件(WAR,ZIP,POM等等)的地方。
Maven 仓库有两种类型:
- 本地(local)
- 远程(remote)(中央(central)也算一种远程仓库)
2.1 本地仓库
运行 Maven 的时候,Maven 所需要的任何构件都是直接从本地仓库获取的。如果本地仓库没有,它会首先尝试从远程仓库下载构件至本地仓库,然后再使用本地仓库的构件。
在本地仓库中已存在的构件,包括从远程仓库获取的以及本地项目install进去的项目,都是最先优先级被被项目使用的
本地仓库默认路径为 本机用户下: .m2/respository/ 文件夹,也可以在settings.xml中指定本地仓库路径
<localRepository>/path/to/local/repo</localRepository>
2.2 远程仓库
2.2.1 中央仓库(central)
中央仓库是maven最核心的仓库,也是默认使用的仓库。中央仓库由 Maven 社区提供,包含了绝大多数流行的开源Java构件,以及源码、作者信息、SCM、信息、许可证信息等。一般来说,简单的Java项目依赖的构件都可以在这里下载到。
中央仓库Nexus
2.2.2 发布项目到maven中央仓库
后面找时间单独写一篇发布日记
2.2.3 自定义仓库,私服
由于中央仓库的开源等条件限制,很多构件并不会发布到中央仓库,很多组织或单位就定制了自己的仓库,包含了所需要的代码库或者其他工程中用到的构件。
2.3 远程仓库使用与配置
emsp; 在日常项目开发中,不同项目,可能需要用到不同的远程仓库来下载构件,我们通常使用一下两种方式来维护远程仓库地址:
- 在settings.xml中定义仓库
- 在项目pom.xml中指定仓库
2.3.1 在settings.xml中定义仓库
emsp; 默认情况下,远程仓库使用的就是中央仓库,但受限于国内网络环境,我们通常使用国内镜像仓库,比如阿里云Maven仓库。
使用<mirror></mirror>标签来指定要使用的仓库
<mirrors>
<mirror>
<id>aliyunmaven</id>
<name>aliyun maven</name>
<url>https://maven.aliyun.com/repository/public/</url>
<mirrorOf>central</mirrorOf>
</mirror>
</mirrors>
属性 | 描述 |
---|---|
id | 镜像标识(唯一) |
name | 镜像描述 |
url | 仓库地址 |
mirrorOf | 仓库匹配模式 |
mirrorOf 仓库匹配模式
属性 | 描述 |
---|---|
central | 指向中央仓库的构件匹配到本仓库 |
* | 匹配所有构件到本仓库 |
repo1,repo2 | 匹配仓库repo1和repo2,使用逗号分隔多个远程仓库 |
*,!repo1: | 匹配除repo1外所有远程仓库,使用感叹号将仓库从匹配中排除 |
需要注意的是,由于镜像仓库完全屏蔽了被镜像仓库,当镜像仓库不稳定或者停止服务的时候,Maven仍将无法访问被镜像仓库,因而将无法下载构件。
2.3.2 常用远程仓库
- 阿里中央仓库
<repository>
<id>alimaven</id>
<name>aliyun maven</name>
<url>http://maven.aliyun.com/nexus/content/groups/public/</url>
</repository>
- camunda.com 中央仓库
<repository>
<id>activiti-repos2</id>
<name>Activiti Repository 2</name>
<url>https://app.camunda.com/nexus/content/groups/public</url>
</repository>
- spring.io 中央仓库
<repository>
<id>springsource-repos</id>
<name>SpringSource Repository</name>
<url>http://repo.spring.io/release/</url>
</repository>
- maven.apache.org 中央仓库
<repository>
<id>central-repos</id>
<name>Central Repository</name>
<url>http://repo.maven.apache.org/maven2</url>
</repository>
- maven.org 中央仓库
<repository>
<id>central-repos1</id>
<name>Central Repository 2</name>
<url>http://repo1.maven.org/maven2/</url>
</repository>
- alfresco.com 中央仓库
<repository>
<id>activiti-repos</id>
<name>Activiti Repository</name>
<url>https://maven.alfresco.com/nexus/content/groups/public</url>
</repository>
2.3.3 pom.xml中定义仓库
通过<repositories></repositories>配置库,这样配置的库仅适用于当前项目。
repositorie的主要参数
属性 | 描述 |
---|---|
id | 库的ID |
url | 库的URL |
releases | 是否启用releases Release版本则代表稳定的版本,发行版本 |
snapshots | 是否启用snapshots Snapshot版本代表不稳定、尚处于开发中的版本,快照版本 |
样例:
<repositories>
<repository>
<id>aliyunmaven</id>
<url>http://maven.aliyun.com/nexus/content/groups/public/</url>
<releases>
<enabled>true</enabled>
</releases>
<snapshots>
<enabled>true</enabled>
</snapshots>
</repository>
</repositories>
2.4 配置仓库认证信息
项目在向仓库推送构件或者拉取构件时,有些仓库需要认证,故需要为指定仓库id配置 认证信息
在settings.xml中配置认证信息
<servers>
<server>
<id>ossrh</id>
<username>qwerwer</username>
<password>asdfasdfasdfe2234dsed+23sdfsfaseafd</password>
</server>
</servers>
3. maven中的父子关系
在一些较大的项目中,我们通常需要将项目合理的拆分成多个不同的子模块,以便于统一的配置管理,代码复用,方便程序的维护与开发。
父模块必须使用 pom 的方式打包如下:
<packaging>pom</packaging>
在父模块中定义要管理的子模块
<modules>
<module>childA</module>
<module>childB</module>
</modules>
3.1 pom.xml 中的 dependencymanagement 和 dependencies
在maven父子关系中,子项目会集成父类大部分配置的。对于我们在项目中需要使用的构件,我们可以使用两种方式来引入:
- 在父类 dependencies 中定义
- 在父类 dependencymanagement 中定义
因为继承关系,两种方式引入的构件,都可以用来在子项目中使用,但用法有区别,也有各自的优势。
3.1.1 dependencies
使用dependencies在父pom中引入构件,此种方式引入的jar可以在所有子模块中使用,使用相同配置,并不需要重新引用,适用于共用构件,举个 :
<dependencies>
<dependency>
<groupId>org.projectlombok</groupId>
<artifactId>lombok</artifactId>
<version>1.18.10</version>
</dependency>
</dependencies>
3.1.2 dependencymanagement
使用dependencymanagement在父pom中引入构件,此种方式引入的jar,若子模块需要使用,则需要重新在<dependencies>标签中使用,父类提供统一的版本控制,举个 :
- 父pom.xml
<dependencyManagement>
<dependencies>
<dependency>
<groupId>org.projectlombok</groupId>
<artifactId>lombok</artifactId>
<version>1.18.10</version>
</dependency>
</dependencies>
</dependencyManagement>
- 子pom.xml
<dependencies>
<dependency>
<groupId>org.projectlombok</groupId>
<artifactId>lombok</artifactId>
</dependency>
</dependencies>
4. maven中构件的版本控制
使用maven中,最让我们头疼的就是jar包的版本,构件之前相互嵌套,不同版本相互依赖,不相兼容,会导致我们在开发中遇到很多奇奇怪怪的问题。
了解版本控制,可以帮我们在遇到麻烦时,快速定位问题。
Maven使用groupId(一般是组织的域名倒写)+ artifactId(库本身的名称) + version(版本)来定义坐标,通过xml来做配置文件。
Maven我会在后面的笔记中,手把手教您一步步上传自己的项目到maven中央仓库
4.1 maven传递依赖
Maven 在 pom.xml 中引入jar包,当Maven解析该依赖时,还需要引入该依赖pom中所依赖的构件以及构件中依赖的构件。这必然会造成同一构件的不用版本同时出现在项目中。
4.1.1 maven的解决方案为:
- 最短路径原则
A -> B -> C -> D(V1)
F -> G -> D(V2)
若某项目想使用构件D,并存在以上依赖关系时,优先使用D(V2),其暴露深度更短。
- 优先原则
如果A-B-X(1.0) ,A-C-X(2.0) 这样的路径长度一样怎么办呢?这样的情况下,maven会根据pom文件声明的顺序加载,如果先声明了B,后声明了C,那就最后的依赖就会是X(1.0)。
- 覆盖优先原则
子pom内声明的优先于父pom中的依赖。
4.1.2 自定义过滤依赖
我们在项目中,可以使用 <exclusions>标签来过滤掉不需要的依赖
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-web</artifactId>
<exclusions>
<exclusion>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-tomcat</artifactId>
</exclusion>
</exclusions>
</dependency>
4.2 maven依赖的版本管理
4.2.1 在 <properties></properties>标签中定义版本号
举个 :
<properties>
<spring-framework-version>4.3.7.REALEASE</spring-framework-version>
</properties>
在引入依赖时使用:
<dependency>
<groupId>org.springframework</groupId>
<artifactId>spring-webmvc</artifactId>
<version>${spring-framework-version}</version>
<scope>compile</scope>
</dependency>
未完待续
更多好玩好看的内容,欢迎到我的博客交流,共同进步 WaterMin
喜欢听相声的朋友,也可以来我的 YouTube,来听郭老师的相声 秋酿
**粗体** _斜体_ [链接](http://example.com) `代码` - 列表 > 引用
。你还可以使用@
来通知其他用户。