Java开发中Maven使用的总结

277 阅读7分钟

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仓库。

使用标签来指定要使用的仓库
 <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 常用远程仓库
  1. 阿里中央仓库
<repository>  
    <id>alimaven</id>
    <name>aliyun maven</name>
    <url>http://maven.aliyun.com/nexus/content/groups/public/</url>
</repository>
  1. camunda.com 中央仓库
<repository>  
    <id>activiti-repos2</id>  
    <name>Activiti Repository 2</name>  
    <url>https://app.camunda.com/nexus/content/groups/public</url>  
</repository>
  1. spring.io 中央仓库
<repository>  
    <id>springsource-repos</id>  
    <name>SpringSource Repository</name>  
    <url>http://repo.spring.io/release/</url>  
</repository>
  1. maven.apache.org 中央仓库
<repository>  
    <id>central-repos</id>  
    <name>Central Repository</name>  
    <url>http://repo.maven.apache.org/maven2</url>  
</repository>
  1. maven.org 中央仓库
<repository>  
    <id>central-repos1</id>  
    <name>Central Repository 2</name>  
    <url>http://repo1.maven.org/maven2/</url>  
</repository>
  1. 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中定义仓库

  通过配置库,这样配置的库仅适用于当前项目。

  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可以在所有子模块中使用,使用相同配置,并不需要重新引用,适用于共用构件,举个:chestnut: :

<dependencies>
    <dependency>
        <groupId>org.projectlombok</groupId>
        <artifactId>lombok</artifactId>
        <version>1.18.10</version>
    </dependency>
</dependencies>
3.1.2 dependencymanagement

  使用dependencymanagement在父pom中引入构件,此种方式引入的jar,若子模块需要使用,则需要重新在标签中使用,父类提供统一的版本控制,举个:chestnut: :

  • 父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 自定义过滤依赖

  我们在项目中,可以使用 标签来过滤掉不需要的依赖

<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 在 标签中定义版本号

举个 :chestnut: :

<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,来听郭老师的相声    秋酿