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)不论是中央仓库中的公共依赖组件,还是公司外部的其他组件,还是自研组件,都直接到私服搜索,如果找到,下载到本地仓库中,以备项目使用;如果没有找到,私服从中央仓库、外部远程仓库下载。