1、Maven的依赖如何存放管理?
Maven中存在依赖组件(常用的是jar包、war包、pom等,也可把Zip包等通过POM文件定义为依赖组件)的地方称为仓库(Repository)。
在Maven中,仓库有三种类型:
- central:中央仓库
- local:本地仓库
- remote:远程仓库
1.1、中央仓库:
Maven的中央仓库是由Maven社区提供的资源仓库,它包含了大量的常用程序库组件(jar包)。默认Maven的中央仓库地址为:http://repo1.maven.org/maven2/
但是实际工作中,由于地域、网络等原因,从Maven中心仓库下载十分慢,可采用公司自建的镜像仓(mirror)或国内地区开放的镜像仓(如:阿里云的镜像仓:http://maven.aliyun.com/nexus/content/groups/public)
如果公司内部和外部有防火墙,并使用了HTTP代理服务组织用户直接访问互联网,这种情况下访问Maven官方中央仓库、或互联网开放的镜像仓,就需要配置proxy。
中央仓库的配置:
Maven默认中央仓库即为http://repo1.maven.org/maven2/,不需要配置什么内容。如果采用镜像,在maven安装目录/conf/setting.xml文件中配置,如下:
(注意:maven安装目录/conf/setting.xml是本地的全局目录,对本地登录的所有用户生效,如果向对指定用户生效,复制setting.xml到user/用户名/.m2下再配置)
<mirrors>
<mirror>
<id>aliyun</id>
<name>aliyun</name>
<url>http://maven.aliyun.com/nexus/content/groups/public</url>
<mirrorOf>central</mirrorOf>
</mirror>
</mirrors>
<mirrorOf>标签表示当前镜像替代的仓库类型,如上central标识当前镜像代替中央仓库。
<mirror>标签在setting.xml文件中可以配置多个,Maven在查找时,并不是按照在setting.xml文件中配置的先后顺序查找的,而是按照id的字母排序来优先查找的。
1.2、本地仓库
本地仓库是在开发人员开发PC上存放Maven依赖的一个文件夹,此文件夹在第一次运行Maven命令时就创建了。
Maven在执行构建任务时,根据依赖关系从中心仓库、或远程仓库下载依赖组件到本地仓库,然后本地仓库的内容供项目引用。
【本地仓库的配置】:本地仓库默认创建在%USER_HOME%\.m2目录下。用户也可以在“setting.xml”中自定义,如:
<localRepository>F:\maven_repository</localRepository>
也可在执行命令时指定本地仓库地址,如:
mvn clean install -Dmaven.repo.local=/home/maven/local_repo/
也可在执行命令时指定配置文件地址,如:
mvn clean install -s /home/maven/settings.xml
1.3、远程仓库
一般在项目开发中,除了引用Maven中央仓库包含的常用程序库组件外,还需要:
(1)项目需要指定外部其他公司、或开源组织的jar包,这些依赖组件通用性等原因,未纳入Maven中央仓库。
(2)公司内部多个项目之间存在依赖,B项目开发过程中需要依赖A.jar。
(3)公司内部定义的各产品需要引用的公共依赖组件,这些依赖组件是公司私有的。
这种情况下,可以在项目的pom.xml中为指定中央仓库以外的其他外部依赖组件仓库【如上(1)的仓库】、及公司内部的私有仓库【如上(2)、(3)的仓库,公司内部私有仓库即私服】,这类仓库称之为远程仓库。
示例:
<repositories>
<repository>
<id>jboss</id>
<name>JBoss Repository</name>
<url>http://repository.jboss.com/maven2/</url>
<releases>
<enabled>true</enabled>
<updatePolicy>daily</updatePolicy>
</releases>
<snapshots>
<enabled>false</enabled>
<checksumPolicy>warn</checksumPolicy>
</snapshots>
<layout>default</layout>
</repository>
<repository>
<id>xxxx</id>
<name>xxxxx</name>
<url>xxxxx</url>
</repository>
</repositories>
<id>:声明远程仓库的唯一id。注意:Maven官方中央仓库的id是central,如果配置中把其他远程仓库的id设置为central,会覆盖Maven官方的中央仓库配置,后续会使用自配置的URI最为中央仓库。
<name>:远程仓库的名称,自定义。
<url>:远程仓库的地址。
<releases>和<snapshots>:标识下载Release版、或Snapshot版依赖组件的权限。通过<enable>标签控制,可以配置一个远程仓库即可以下载Release版、Snapshot版依赖组件,也可以配置两个远程仓库分别下载Release版、Snapshot版依赖组件。
<updatePolicy>:表示依赖组件的更新的频率,默认为daily,在后面下载过程详解部分再做描述。
<checksumPolicy>:用来配置Maven检查校验策略。当构建被部署到Maven仓库时,会同时部署对应的检验和文件。在下载构件时,Maven会验证校验和文件。如果校验和验证失败,当checksumPolicy配置为默认warn时,Maven执行构建时会输出警告;当配置为fail-Maven时,遇到校验和错误构建失败;当配置为ignore时,Maven忽略校验和错误。
如上为 远程仓库定义在某个项目的pom.xml中。但是,如果本地同步开发多个项目,远程仓库是各个项目的公共资源,不希望在每个项目的pom.xml中都配置一份,如何做呢?
答案是:可以把上面的<repositories>标签配置到Maven的setting.xml文件中,配置在<profile>标签内。样例:
<profiles>
<profile>
<id>cloud</id>
<activation>
<activeByDefault>true</activeByDefault>
</activation>
<repositories>
<repository>
<id>central</id>
<url>http://地址:端口/repository/maven-public/</url>
<snapshots>
<enabled>true</enabled>
</snapshots>
</repository>
<repository>
<id>snapshots</id>
<url>http://地址:端口/repository/maven-public/</url>
<snapshots>
<enabled>true</enabled>
</snapshots>
</repository>
</repositories>
<pluginRepositories>
<pluginRepository>
<id>central</id>
<url>http://地址:端口/repository/maven-public/</url>
<snapshots>
<enabled>false</enabled>
<updatePolicy>never</updatePolicy>
</snapshots>
</pluginRepository>
</pluginRepositories>
</profile>
<profile>
<id>downloadSources</id>
<properties>
<downloadSources>true</downloadSources>
<downloadJavadocs>true</downloadJavadocs>
</properties>
</profile>
</profiles>
注意:<profiles>标签内的内容是需要指定激活才生效的,如何激活见本章节末尾。
1.4、Maven 从3类仓库中搜索下载依赖组件的顺序:
当我们执行 Maven 构建命令,Maven 依赖库按以下顺序进行搜索:
(1)搜索本地仓库,如果没有找到,跳到第2步。
(2)搜索中央仓库,如果找到,下载到本地仓库中,以备项目使用;如果没有找到,跳到第3步。
(3)如果自定义了远程仓库,那么也会在远程仓库中进行查找并获得依赖组件,如果都没有找到,那么Maven就会抛出异常。
2、把自研jar放入仓库
1、实际开发中,可能开发人员本地同步在开发A、B多个项目,B.jar依赖A.jar。希望A.jar编译、打包完毕后,A.jar也被Maven管理,通过Maven的依赖机制可以被B项目引用,如何做呢?
答案是:执行Maven的install阶段,这个阶段的作用就是把项目jar包部署到Maven本地仓。
2、在多团队配合开发中,希望自己开发的jar包通过Mave的deploy阶段部署到远程仓库【一般为公司私有远程仓库,即私服】,供其他团队更新引用,如何做的?
答案是:在pom.xml文件中通过<distributionManagement>标签指定。
<!--发布到私服配置-->
<distributionManagement>
<!-- <repository>标签表示Release版本仓, Release版本仓: 用来保存稳定的发行版本 -->
<repository>
<id>releases</id>
<name>releases</name>
<url>http://地址:端口/repository/maven-releases/</url>
</repository>
<!-- <snapshotRepository>标签表示Snapshot版本仓, Snapshot版本仓: 用于保存开发过程中的不稳定版本 -->
<snapshotRepository>
<id>Snapshots</id>
<name>Snapshots</name>
<url>http://地址:端口/repository/maven-snapshots/</url>
</snapshotRepository>
</distributionManagement>
<!--
Maven会根据模块的版本号(pom.xml中定义)是否带有-SNAPSHOT来判断是Snapshot版本还是Release版本。
如果是Snapshot版本,mvn deploy时会自动发布到Snapshot版本仓。
如果是Release版本,mvn deploy时会自动发布到Release版本仓。
-->
如上远程仓库定义在某个项目的pom.xml中。如果本地同步开发多个项目,远程仓库是各个项目的公共资源,不希望在每个项目的pom.xml中都配置一份,如何做呢?
答案是:可以把上面的<distributionManagement>标签配置到Maven的setting.xml文件中,配置在<profile>标签内。
<profiles>
<profile>
<distributionManagement>
<repository>
<id>releases</id>
<name>releases</name>
<url>http://地址:端口/repository/maven-releases/</url>
</repository>
<snapshotRepository>
<id>Snapshots</id>
<name>Snapshots</name>
<url>http://地址:端口/repository/maven-snapshots/</url>
</snapshotRepository>
</distributionManagement>
</profile>
</profiles>
注意:<profiles>标签内的内容是需要指定激活才生效的,如何激活见本章节末尾。
3、远程仓库的认证
出于安全考虑,有些远程仓库是需要我们访问认证的,这种情况下就需要配置认证信息。和配置远程仓库地址不同,远程仓库可以配置在项目的pom.xml中。但是,远程仓库认证信息只能配置在Maven的setting.xml文件中。
原因是,项目的pom.xml属于项目源码的一部分,是需要上传到git仓库的。如果你的认证信息存放在pom.xml中,则项目的所有成员都可以看到你的用户名、密码。而setting.xml则保存在开发人员本地环境。因此,在settings.xml中配置认证信息更为安全。
setting.xml中配置远程仓库认证信息样例:
<servers>
<server>
<id>releases</id>
<username>用户名</username>
<password>密码</password>
</server>
<server>
<id>Snapshots</id>
<username>用户名</username>
<password>密码</password>
</server>
</servers>
注意:这里<id>信息十分重要,这个<id>标签信息必须和pom.xml中配置的远程仓库的<id>保持一致,Maven是通过<id>为配置的远程仓库找到正确的认证信息的。
4、<profiles>标签内的内容激活方式
4.1、方式一:
执行mvn命令时,通过-D参数激活。
4.2、方式二:
pom.xml或setting.xml中的<profiles>内的内容通过<activation>指定条件激活。
样例1:默认激活
<profile>
<id>dev</id>
<activation>
<activeByDefault>true</activeByDefault>
</activation>
...
</profile>
样例2:条件激活。指定JDK版本激活、根据操作系统参数激活、根据Maven 属性等激活等。
<profile>
<id>dev</id>
<activation>
<activeByDefault>false</activeByDefault>
<jdk>1.5</jdk>
<os>
<name>Windows XP</name>
<family>Windows</family>
<arch>x86</arch>
<version>5.1.2600</version>
</os>
<property>
<name>mavenVersion</name>
<value>2.0.5</value>
</property>
<file>
<exists>file2.properties</exists>
<missing>file1.properties</missing>
</file>
</activation>
...
</profile>
4.3、方式三:
setting.xml中的<profiles>内的内容可以通过<activeProfiles>标签激活。
样例:
<profiles>
<profile>
<id>profileTest1</id>
......
</profile>
</profiles>
<activeProfiles>
<activeProfile>profileTest1</activeProfile>
</activeProfiles>
5、私服
公司内部实际使用中,可能存在:
(1)公司内部很多团队都在开发项目,每个团队的每个组员都需要下载依赖组件,如果全部使用外部中央仓库/镜像、远程仓库,回存在:
- 外部公共仓库如果不是那么稳定、或者由大家都在下载速度慢,影响开效率。
- 公司内部和外部如果是租用带宽,每个项目、每个成员都从外部下载, 带宽占用情况、费用高。
(2)另外,公司内部也可能存在私有的依赖组件,需要在公司内部共享:
- 公司内部多个项目之间存在依赖,B项目开发过程中需要依赖A.jar。
- 公司内部定义的各产品需要引用的公共依赖组件,这些依赖组件是公司私有的。
这种情况下,就可以在公司内部搭建一个私服仓库。私服是一种特殊的远程仓库。私服仓库和中心仓库、本地仓库、镜像仓库的关系如下:
此时,私服的作用:
(1)可以代理任何外部的公共仓库,包括中央仓库、公共远程仓库。因此,对于公司内的Maven用户来说,使用一个私服地址就等于使用了所有需要的外部仓库。Maven需要的所有外部组件都可以优先从私服下载,私服中没有,私服再从公共仓库下载。此时私服即为所有外部仓库(中心仓库、远程仓库)的镜像。
(2)作为公司内自研依赖组件的归档、下载远程仓库。
5.1、私服搭建
详见:https://www.cnblogs.com/caoweixiong/p/10522400.html
5.2、配置私服
参考前面1、2、3章节,把<mirror>、远程仓库、自研上传仓库设置为私服地址,根据需要设置私服仓库认证。
5.3、私服配置后,下载依赖组件的顺序:
(1)搜索本地仓库,如果没有找到,跳到第2步。
(2)不论是中央仓库中的公共依赖组件,还是公司外部的其他组件,还是自研组件,都直接到私服搜索,如果找到,下载到本地仓库中,以备项目使用;如果没有找到,私服从中央仓库、外部远程仓库下载。