`
juvenshun
  • 浏览: 1593989 次
  • 性别: Icon_minigender_1
  • 来自: 苏州
社区版块
存档分类
最新评论

Maven最佳实践:Maven仓库

阅读更多

什么是Maven仓库

在不用Maven的时候,比如说以前我们用Ant构建项目,在项目目录下,往往会看到一个名为/lib的子目录,那里存放着各类第三方依赖jar文件,如log4j.jar,junit.jar等等。每建立一个项目,你都需要建立这样的一个/lib目录,然后复制一对jar文件,这是很明显的重复。重复永远是噩梦的起点,多个项目不共用相同的jar文件,不仅会造成磁盘资源的浪费,也使得版本的一致性管理变得困难。此外,如果你使用版本管理工具,如SVN(你没有使用版本管理工具?马上试试SVN吧,它能帮你解决很多头疼的问题),你需要将大量的jar文件提交到代码库里,可是版本管理工具在处理二进制文件方面并不出色。

Maven仓库就是放置所有JAR文件(WAR,ZIP,POM等等)的地方,所有Maven项目可以从同一个Maven仓库中获取自己所需要的依赖JAR,这节省了磁盘资源。此外,由于Maven仓库中所有的JAR都有其自己的坐标,该坐标告诉Maven它的组ID,构件ID,版本,打包方式等等,因此Maven项目可以方便的进行依赖版本管理。你也不在需要提交JAR文件到SCM仓库中,你可以建立一个组织层次的Maven仓库,供所有成员使用。

简言之,Maven仓库能帮助我们管理构件(主要是JAR)。

 

本地仓库 vs. 远程仓库

运行Maven的时候,Maven所需要的任何构件都是直接从本地仓库获取的。如果本地仓库没有,它会首先尝试从远程仓库下载构件至本地仓库,然后再使用本地仓库的构件。

比如说,你的项目配置了junit-3.8的依赖,在你运行mvn test 的时候,Maven需要使用junit-3.8的jar文件,它首先根据坐标查找本地仓库,如果找到,就直接使用。如果没有,Maven会检查可用的远程仓库配置,然后逐个尝试这些远程仓库去下载junit-3.8的jar文件,如果远程仓库存在该文件,Maven会将其下载到本地仓库中,继而使用。如果尝试过所有远程仓库之后,Maven还是没能够下载到该文件,它就会报错。

Maven缺省的本地仓库地址为${user.home}/.m2/repository 。也就是说,一个用户会对应的拥有一个本地仓库。

你也可以自定义本地仓库的位置,修改${user.home}/.m2/settings.xml

<settings>
  ...
  <localRepository>D:\java\repository</localRepository>
  ...
</settings>

你还可以在运行时指定本地仓库位置:

mvn clean install -Dmaven.repo.local=/home/juven/myrepo/

还有一点需要理解的是,当我们运行install的时候,Maven实际上是将项目生成的构件安装到了本地仓库,也就是说,只有install了之后,其它项目才能使用此项目生成的构件。

了解了本地仓库,接着了解一下Maven缺省的远程仓库,即Maven中央仓库。

安装好Maven之后,我们可以建立一个简单的项目,配置一些简单的依赖,然后运行mvn clean install,项目就构建好了。我们没有手工的去下载任何jar文件,这一切都是因为Maven中央仓库的存在,当Maven在本地仓库找不到需要的jar文件时,它会查找远程仓库,而一个原始的Maven安装就自带了一个远程仓库——Maven中央仓库。

这个Maven中央仓库是在哪里定义的呢?在我的机器上,我安装了maven-2.0.10,我可以找到这个文件:${M2_HOME}/lib/maven-2.0.10-uber.jar ,打开该文件,能找到超级POM:\org\apache\maven\project\pom-4.0.0.xml ,它是所有Maven POM的父POM,所有Maven项目继承该配置,你可以在这个POM中发现如下配置:

  <repositories>
    <repository>
      <id>central</id>
      <name>Maven Repository Switchboard</name>
      <layout>default</layout>
      <url>http://repo1.maven.org/maven2</url>
      <snapshots>
        <enabled>false</enabled>
      </snapshots>
    </repository>
  </repositories>

关于远程仓库的配置,下面的小节我会详细解释,这里我们只要知道,中央仓库的id为central,远程url地址为http://repo1.maven.org/maven2,它关闭了snapshot版本构件下载的支持。

 

在POM中配置远程仓库

前面我们看到超级POM配置了ID为central的远程仓库,我们可以在POM中配置其它的远程仓库。这样做的原因有很多,比如你有一个局域网的远程仓库,使用该仓库能大大提高下载速度,继而提高构建速度,也有可能你依赖的一个jar在central中找不到,它只存在于某个特定的公共仓库,这样你也不得不添加那个远程仓库的配置。

这里我配置一个远程仓库指向中央仓库的中国镜像:

<project>
...
  <repositories>
    <repository>
      <id>maven-net-cn</id>
      <name>Maven China Mirror</name>
      <url>http://maven.net.cn/content/groups/public/</url>
      <releases>
        <enabled>true</enabled>
      </releases>
      <snapshots>
        <enabled>false</enabled>
      </snapshots>
    </repository>
  </repositories>
  <pluginRepositories>
    <pluginRepository>
      <id>maven-net-cn</id>
      <name>Maven China Mirror</name>
      <url>http://maven.net.cn/content/groups/public/</url>
      <releases>
        <enabled>true</enabled>
      </releases>
      <snapshots>
        <enabled>false</enabled>
      </snapshots>    
    </pluginRepository>
  </pluginRepositories>
...
</project>

我们先看一下<repositories>的配置,你可以在它下面添加多个<repository> ,每个<repository>都有它唯一的ID,一个描述性的name,以及最重要的,远程仓库的url。此外,<releases><enabled>true</enabled></releases>告诉Maven可以从这个仓库下载releases版本的构件,而<snapshots><enabled>false</enabled></snapshots>告诉Maven不要从这个仓库下载snapshot版本的构件。禁止从公共仓库下载snapshot构件是推荐的做法,因为这些构件不稳定,且不受你控制,你应该避免使用。当然,如果你想使用局域网内组织内部的仓库,你可以激活snapshot的支持。

关于<repositories>的更详细的配置及相关解释,请参考:http://www.sonatype.com/books/maven-book/reference_zh/apas02s08.html。

至于<pluginRepositories>,这是配置Maven从什么地方下载插件构件(Maven的所有实际行为都由其插件完成)。该元素的内部配置和<repository>完全一样,不再解释。

 

在settings.xml中配置远程仓库

我们知道了如何在POM中配置远程仓库,但考虑这样的情况:在一个公司内部,同时进行这3个项目,而且以后随着这几个项目的结束,越来越多的项目会开始;同时,公司内部建立一个Maven仓库。我们统一为所有这些项目配置该仓库,于是不得不为每个项目提供同样的配置。问题出现了,这是重复

其实我们可以做到只配置一次,在哪里配置呢?就是settings.xml。

不过事情没有那么简单,不是简单的将POM中的<repositories>及<pluginRepositories>元素复制到settings.xml中就可以,setting.xml不直接支持 这两个元素。但我们还是有一个并不复杂的解决方案,就是利用profile,如下:

<settings>
  ...
  <profiles>
    <profile>
      <id>dev</id>
      <!-- repositories and pluginRepositories here-->
    </profile>
  </profiles>
  <activeProfiles>
    <activeProfile>dev</activeProfile>
  </activeProfiles>
  ...
</settings>

这里我们定义一个id为dev的profile,将所有repositories以及pluginRepositories元素放到这个profile中,然后,使用<activeProfiles>元素自动激活该profile。这样,你就不用再为每个POM重复配置仓库。

使用profile为settings.xml添加仓库提供了一种用户全局范围的仓库配置。

 

镜像

如果你的地理位置附近有一个速度更快的central镜像,或者你想覆盖central仓库配置,或者你想为所有POM使用唯一的一个远程仓库(这个远程仓库代理的所有必要的其它仓库),你可以使用settings.xml中的mirror配置。

以下的mirror配置用maven.net.cn覆盖了Maven自带的central:

<settings>
...
  <mirrors>
    <mirror>
      <id>maven-net-cn</id>
      <name>Maven China Mirror</name>
      <url>http://maven.net.cn/content/groups/public/</url>
      <mirrorOf>central</mirrorOf>
    </mirror>
  </mirrors>
...
</settings>

 

这里唯一需要解释的是<mirrorOf>,这里我们配置central的镜像,我们也可以配置一个所有仓库的镜像,以保证该镜像是Maven唯一使用的仓库:

<settings>
...
  <mirrors>
    <mirror>
      <id>my-org-repo</id>
      <name>Repository in My Orgnization</name>
      <url>http://192.168.1.100/maven2</url>
      <mirrorOf>*</mirrorOf>
    </mirror>
  </mirrors>
...
</settings>

关于更加高级的镜像配置,可以参考:http://maven.apache.org/guides/mini/guide-mirror-settings.html。

 

分发构件至远程仓库

mvn install 会将项目生成的构件安装到本地Maven仓库,mvn deploy 用来将项目生成的构件分发到远程Maven仓库。本地Maven仓库的构件只能供当前用户使用,在分发到远程Maven仓库之后,所有能访问该仓库的用户都能使用你的构件。

我们需要配置POM的distributionManagement来指定Maven分发构件的位置,如下:

<project>  
  ...  
  <distributionManagement>  
    <repository>  
      <id>nexus-releases</id>  
      <name>Nexus Release Repository</name>  
      <url>http://127.0.0.1:8080/nexus/content/repositories/releases/</url>  
    </repository>  
    <snapshotRepository>  
      <id>nexus-snapshots</id>  
      <name>Nexus Snapshot Repository</name>  
      <url>http://127.0.0.1:8080/nexus/content/repositories/snapshots/</url>  
    </snapshotRepository>  
  </distributionManagement>  
  ...  
</project>  

Maven区别对待release版本的构件和snapshot版本的构件,snapshot为开发过程中的版本,实时,但不稳定,release版本则比较稳定。Maven会根据你项目的版本来判断将构件分发到哪个仓库。

一般来说,分发构件到远程仓库需要认证,如果你没有配置任何认证信息,你往往会得到401错误。这个时候,如下在settings.xml中配置认证信息:

<settings>  
  ...  
  <servers>  
    <server>  
      <id>nexus-releases</id>  
      <username>admin</username>  
      <password>admin123</password>  
    </server>  
    <server>  
      <id>nexus-snapshots</id>  
      <username>admin</username>  
      <password>admin123</password>  
    </server>    
  </servers>  
  ...  
</settings>

需要注意的是,settings.xml中server元素下id的值必须与POM中repository或snapshotRepository下id的值完全一致。将认证信息放到settings下而非POM中,是因为POM往往是它人可见的,而settings.xml是本地的。

 

小结

本文介绍了Maven仓库,它是什么?本地仓库,远程仓库,中央仓库具体是指什么?并介绍了如何在POM中配置项目层次的仓库,在settings中配置用户层次的仓库,以及mirror。本文还介绍了如何安装构件到本地仓库,如何分发构件至仓库。

67
3
分享到:
评论
19 楼 charis0721 2016-02-03  
zhuyanjavaeye 写道
请教一个问题,如果在settings.xml中配置了repository,在自己的pom.xml中也配置了repository,那么下载jar的时候,顺序是什么样的?先从settings.xml中指定的下载?没有了再到自己的pom.xml中指定的去下载?


如果settings.xml中有mirror,三者的顺序又是怎样的?

我的理解:如果没有mirror,优先项目pom中加载,没有再去settings.xml中加载;
如果有mirror,优先项目pom中加载,没有再去settings.xml中加载,再没有去mirror中加载。

但是我现在遇到个问题,感觉有mirror的时候优先mirror了,而且没有再用pom中指定的库,求解??
18 楼 zhuyanjavaeye 2016-01-11  
请教一个问题,如果在settings.xml中配置了repository,在自己的pom.xml中也配置了repository,那么下载jar的时候,顺序是什么样的?先从settings.xml中指定的下载?没有了再到自己的pom.xml中指定的去下载?
16 楼 map612 2014-07-23  
已阅,有收获,多谢
15 楼 永志_爱戴 2014-02-28  
好文章,果断收藏,期待楼主的下一篇
14 楼 Allen_J_Will 2014-01-09  
Martin_Bonnie 写道
按照大牛说明 已经成功弄好 ,但是有一个问题,我在项目中使用了
<plugin>
				<groupId>org.apache.maven.plugins</groupId>
				<artifactId>maven-assembly-plugin</artifactId>
				<version>2.4</version>
				<executions>
					<execution>
						<id>make-client-jar</id>
						<phase>package</phase>
						<goals>
							<goal>single</goal>
						</goals>
						<configuration>
							<skipAssembly>false</skipAssembly>
							<finalName>express-basicdata-service</finalName>
							<appendAssemblyId>false</appendAssemblyId>
							<descriptors>
								<descriptor>src/main/assembly/xingng-client-jar.xml</descriptor>
							</descriptors>
						</configuration>
					</execution>
				</executions>
			</plugin>


maven-assembly-plugin的插件,我想将这个插件打出来的jar文件自动发布到远程的snapshot库中,配置的deployManage好像是当前工程的pom文件的。  不知道怎么弄了,求指教 谢谢。


这个配置和构件发布到远程无关,不要混淆了。
构件发布远程,需要配置<distributionManagement>标签,一般还要求授权
13 楼 Martin_Bonnie 2013-12-09  
按照大牛说明 已经成功弄好 ,但是有一个问题,我在项目中使用了
<plugin>
				<groupId>org.apache.maven.plugins</groupId>
				<artifactId>maven-assembly-plugin</artifactId>
				<version>2.4</version>
				<executions>
					<execution>
						<id>make-client-jar</id>
						<phase>package</phase>
						<goals>
							<goal>single</goal>
						</goals>
						<configuration>
							<skipAssembly>false</skipAssembly>
							<finalName>express-basicdata-service</finalName>
							<appendAssemblyId>false</appendAssemblyId>
							<descriptors>
								<descriptor>src/main/assembly/xingng-client-jar.xml</descriptor>
							</descriptors>
						</configuration>
					</execution>
				</executions>
			</plugin>


maven-assembly-plugin的插件,我想将这个插件打出来的jar文件自动发布到远程的snapshot库中,配置的deployManage好像是当前工程的pom文件的。  不知道怎么弄了,求指教 谢谢。
12 楼 semmy 2013-10-22  
按我的经验,这两个都要配置的,如果没有配置mirror,只是单单配置了一个profile,那么还是会从默认的:http://repo.maven.apache.org/maven2 中央仓库下载依赖包。
galen888 写道
请问想配置访问自己的私服仓库 mirror 和 <profiles>  都需要配置吗

例如:
<mirrors> 
    <mirror> 
      <id>my-org-repo</id> 
      <name>Repository in My Orgnization</name> 
      <url>http://192.168.1.100/maven2</url> 
      <mirrorOf>*</mirrorOf> 
    </mirror> 
  </mirrors>



<profiles> 
    <profile> 
      <id>dev</id> 
      <!-- repositories and pluginRepositories here-->

       省略自己的IP
    </profile> 
  </profiles> 
  <activeProfiles> 
    <activeProfile>dev</activeProfile> 
  </activeProfiles>





11 楼 galen888 2013-10-10  
请问想配置访问自己的私服仓库 mirror 和 <profiles>  都需要配置吗

例如:
<mirrors> 
    <mirror> 
      <id>my-org-repo</id> 
      <name>Repository in My Orgnization</name> 
      <url>http://192.168.1.100/maven2</url> 
      <mirrorOf>*</mirrorOf> 
    </mirror> 
  </mirrors>



<profiles> 
    <profile> 
      <id>dev</id> 
      <!-- repositories and pluginRepositories here-->

       省略自己的IP
    </profile> 
  </profiles> 
  <activeProfiles> 
    <activeProfile>dev</activeProfile> 
  </activeProfiles>





10 楼 b_l_east 2013-07-04  
GOOD
9 楼 succeedloveaaaa 2013-03-05  
在网上找了很多,只有你的我看懂了,谢谢博主
8 楼 eksliang 2012-09-10  
真的讲的很好。
7 楼 zhubinhua 2012-05-12  
请问一下:
Snapshots 这个Repositories如何上传一个maven中央仓库没有的jar包呀??
6 楼 yangpeihai 2011-12-28  
刚刚学习maven,楼主博客给了我非常大的帮帮助,非常谢谢
5 楼 LXJ_hmxc 2010-01-25  
讲的挺详细和挺实用的
  
4 楼 juvenshun 2009-08-06  
q3691223 写道
问下如何在pom.xml里面开启snapshot的jar包下载?给个例子指导下

#   <repositories> 
#     <repository> 
#       <id>maven-net-cn</id> 
#       <name>Maven China Mirror</name> 
#       <url>http://maven.net.cn/content/groups/public/</url> 
#       <releases> 
#         <enabled>true</enabled> 
#       </releases> 
#       <snapshots> 
#         <enabled>true</enabled> 
#       </snapshots> 
#     </repository> 
#   </repositories> 
3 楼 q3691223 2009-08-05  
问下如何在pom.xml里面开启snapshot的jar包下载?给个例子指导下
2 楼 juvenshun 2009-04-06  
hxirui 写道

引用其实我们可以做到只配置一次,在哪里配置呢?就是settings.xml。
这句没看明白,所谓只配置一次指的是什么?引用settings.xml是哪个地方的?
请指教。

全局范围:M2_HOME/conf/settings.xml(安装自带这个文件)
用户范围:USER_HOME/.m2/settings.xml(该文件默认不存在,可复制全局范围settings.xml至此)
“只配置一次”是指“只需要在settings.xml中进行一次仓库配置,那么只要是在该settings.xml的影响范围内,所有的项目(POM)就都能自动使用该仓库配置”
1 楼 hxirui 2009-04-05  
引用
其实我们可以做到只配置一次,在哪里配置呢?就是settings.xml。

这句没看明白,所谓只配置一次指的是什么?
引用
settings.xml
是哪个地方的?
请指教。

相关推荐

    MAVEN使用最佳实践

    【MAVEN使用最佳实践】 Maven 是一个强大的项目管理和构建工具,它简化了Java应用程序的构建过程,通过一套约定优于配置的原则,使得项目构建、依赖管理和文档生成等工作变得标准化。以下是一些在使用Maven时可以...

    maven-repo:Maven 存储库

    10. 使用Maven仓库的最佳实践: - 保持pom.xml文件的整洁,避免引入不必要的依赖。 - 对于公司内部的项目,推荐使用私有仓库托管,以防止版本冲突和敏感信息泄露。 - 定期更新依赖,以获取最新的安全修复和功能...

    maven_archetype

    - **版本控制**:archetype 可以随着项目需求的变化而更新,新版本的 archetype 会包含最新的最佳实践和依赖。 ### Maven Archetype 的配置文件 每个 archetype 都有一个配置文件,通常是 `archetype-metadata.xml...

    Maven原理和实践-培训课件.ppt

    何为Maven 构建,依赖管理,项目信息聚合 Maven核心概念 坐标,依赖,仓库,生命周期,插件 Maven最佳实践 创建、打包、发布、版本管理 项目实战 Nexus(Todo…) M2eclipse(Todo…)

    maven-plugins:[不建议使用] Apache Maven插件的镜像

    而`maven-install-plugin`则将构建好的工件安装到本地Maven仓库,方便后续依赖。 如果"maven-plugins:[不建议使用]"中包含了这些插件的旧版本,可能会导致的问题包括:与现代Java版本的兼容性问题,不支持新的...

    maven-parent:Apache Maven项目父POM

    这个"maven-parent"主要被Apache的各个子项目引用,为它们提供一致性和最佳实践。 标题 "maven-parent:Apache Maven项目父POM" 指出这个压缩包包含的是与Maven的父POM相关的源代码和配置。这个父POM包含了各种默认...

    Maven The Complete Reference

    **3.6 POM 最佳实践** - **3.6.1 依赖分组**:将相关的依赖放在一起,方便管理和查找。 - **3.6.2 多模块与继承** - **3.6.2.1 简单项目**:对于较小的项目,可以使用单一的 POM 文件来管理整个项目。 - **3.6....

    <<Maven权威指南>>+<<Maven in Action>> pdf扫描版丛书

    1. Maven最佳实践:提供了一些实际项目中如何有效使用Maven的经验和建议。 2. 敏捷开发与持续集成:讲解如何利用Maven与敏捷开发方法(如Scrum、XP)结合,以及如何与持续集成工具(如Jenkins、Hudson)集成。 3. ...

    Maven原理与实践[汇编].pdf

    - 指导开发:Maven提供了Java项目的最佳实践,通过预设的项目结构,自动生成项目骨架。 - 自动编译:Maven不仅能自动编译源码,还能执行测试、打包、部署、文档生成等一系列任务。 - 依赖管理:Maven通过仓库管理...

    Maven.Definitive.Guide

    10. Maven的最佳实践: - 保持POM简洁,避免过度配置。 - 使用最新的稳定Maven版本,及时更新依赖。 - 为项目创建清晰的模块结构,便于维护和扩展。 通过阅读《Maven 完全指南》,读者可以全面了解Maven的工作...

    apache-maven-3.6.0-src

    **Maven的最佳实践:** 1. **约定优于配置**:Maven遵循一套标准目录结构,如`src/main/java`存放源代码,`src/test/java`放测试代码。 2. **依赖管理**:避免硬编码版本号,尽可能利用传递性依赖,保持POM简洁。 3....

    maven帮助文档

    通过深入学习这份"Maven帮助文档",开发者不仅可以掌握Maven的基本操作,还能理解其背后的原理和最佳实践,从而提升项目构建的效率和质量。无论你是初学者还是经验丰富的开发者,这份文档都将是你宝贵的参考资料。

    ojdbc6 解决maven缺失问题

    在Java开发过程中,Maven作为项目管理和构建工具,起着至关重要的作用。然而,有时我们可能会遇到Maven无法找到...在进行这种操作时,也建议时刻关注Oracle官方的更新和最佳实践,确保使用的驱动是最安全和兼容的版本。

    maven_study:学习 Apache Maven

    10. **最佳实践**:提供一些Maven使用的最佳实践和常见问题解决方案。 通过深入学习和实践这个`maven_study-master`中的内容,你将能够熟练掌握Maven的使用,提高开发效率,并能更好地理解和融入Java社区的开发规范...

    maven_training:TP_Maven

    "maven_training:TP_Maven"这个项目显然是一个关于Maven的训练材料,旨在帮助开发者掌握Maven的核心概念和最佳实践。 Maven使用一种标准的项目对象模型(Project Object Model,POM),定义了项目的配置信息,包括...

    maven 自动发布更新本地和远程仓库

    在这个场景下,我们讨论的是如何利用 Maven 将项目自动发布到本地和远程Maven仓库,以便于团队成员共享和进一步的部署。 1. **Maven生命周期**: Maven 的生命周期包括清洁(clean)、构建(compile)、测试(test...

    2024版Maven仓库清除工具

    Maven仓库在Java开发中...通过使用这样的工具,开发者能够更好地管理他们的Maven仓库,确保其整洁、高效,并符合最佳实践。在日常开发工作中,定期进行仓库清理已经成为不可或缺的一环,以确保项目的可维护性和持续性。

    Maven权威指南中文完整版清晰

    Maven仓库分为本地仓库、中央仓库和远程仓库,中央仓库是默认的依赖来源。 4. 构建生命周期与阶段: Maven拥有一个清晰的构建生命周期,包括clean、default和site三个生命周期。default生命周期中包含compile、...

    maven学习笔记:有关更多笔记,请参阅关于学习的笔记和代码

    本笔记将深入探讨Maven的核心概念、使用方法以及最佳实践。 【描述】:本笔记旨在帮助开发者更好地掌握Maven,包括其基本用法、配置技巧和常见问题解决。通过阅读和实践这些笔记,你将能够更高效地利用Maven进行...

Global site tag (gtag.js) - Google Analytics