关闭

GitChat · 软件工程 | 一小时教你学会 Maven 项目的构建与管理

标签: maven开源项目软件工程
1274人阅读 评论(3) 收藏 举报
分类:

GitChat 作者:梁鹏举
原文: 一小时教你学会 Maven 项目的构建与管理
关注公众号:GitChat 技术杂谈,一本正经的讲技术

Maven翻译成中文是“专家、内行”。Maven是Apache组织中一个颇为成功的开源项目,Maven主要服务于基于Java平台的项目构建、依赖管理和项目信息管理的优秀工具。

Maven是优秀的构建工具:自动化构建过程、跨平台、标准化构建过程。

Maven为Java开发者提供了一个免费的中央仓库,其中几乎可以找到任何流行的开源类库,通过Maven的衍生工具Nexus,可以进行快速的搜索。Maven项目目录结构有约定的规则,约定优于配置(Convention Over Configuration)。

Ant(Another Neat Tool)另一个整洁的工具,Tomcat构建,过程式,开发者需要显式的指定每一个目标以及完成该目标所需要执行的任务,每一个项目都需要重新编写这一过程。

Maven是声明式的,项目构建过程和过程各阶段所需工作都要插件实现,大部分插件都是现成的,开发者只需要声明项目的基本元素,Maven就可以执行内置的,完整的构建过程。

Maven 基础环境配置与基本命令

Maven的安装与配置分析

Maven环境的安装

安装环境:Jdk1.7、Maven-3.5.0

第一步:JDK安装与配置。Windows和Linux下安装步骤可自行查找。

第二步:Maven的下载。官方下载地址:http://maven.apache.org/download.cgi

当前最新版本3.5.0,Windows上安装下载apache-maven-3.5.0-bin.zip

Linux上安装下载 apache-maven-3.5.0-bin.tar.gz

Windows上安装Maven步骤:

  • 解压apache-maven-3.5.0-bin.zip到D:\develop\apache-maven-3.5.0

  • 配置环境变量

    M2_HOME=D:\develop\apache-maven-3.5.0

    Path末尾添加;% M2_HOME%\bin

  • 测试安装是否正确

    在命令行执行mvn –v,可以maven版本信息和基本配置信息表示配置成功。

Linux上安装Maven步骤:

  • 解压tar xzvf apache-maven-3.5.0-bin.tar.gz

  • 配置环境变量

    export M2_HOME = /home/develop/apache-maven-3.5.0

    export PATH = PATH;M2_HOME/bin

  • 测试安装是否正确

    echo $M2_HOME 输出环境变量路径

    mvn -v 输出版本号等相关信息

安装目录分析

Maven安装目录结构

说明:

bin:该目录下mvn、mvnDebug是基于Linux平台的shell脚本,mvn.bat、mvnDebug.bat是基于Windows平台的bat脚本,在命令行输入mvn命令时实际上是调用mvn或mvn.bat脚本。mvn和mvnDebug的区别是mvnDebug多了一条MAVEN_DEBUG_OPTS配置,作用是运行Maven时开启debug模式以调试Maven本身。m2.conf文件是classworlds的配置文件,Maven启动时会自动加载。

boot: 该目录只包含一个文件plexus-classworlds-2.5.2.jar,plexus-classworlds是一个类加载器框架,相对于默认的java类加载器,它提供了更加丰富的语法以便配置,Maven使用该框架加载自己的类库。

conf: 该目录包含了Maven的配置文件settings.xml,可以指定2种级别:全局级别:直接修改maven.conf/settings.xmlMaven{user.home}/.m2/目录下,然后修改settings.xml配置,在当前用户范围内定制Maven的行为。

lib: 该目录包含了所有Maven运行时需要的Java类库,Maven本身是分模块的maven-*.jar都是maven自己的包,还有很多第三方依赖包。

LICENSE: Maven使用的软件许可证是Apache LicenseVersion 2.0。

NOTICE: Apache Maven Distribution使用的第三方软件。

README.txt: Maven的简明介绍,包括系统要求、安装说明、Maven URLS等。

Maven的基本命令

Maven项目构建过程中,主要构建命令有几种:

  • mvn validate 验证,验证项目是正确的并且所有的信息是可用的;

  • mvn clean 清理,清理项目缓存输出,一般是target文件夹被删除;

  • mvn compile 编译,将java源文件编译成.class文件;

  • mvn test 测试,生成测试报告,运行test目录下的所有单元测试;

  • mvn package 打包,将项目打成jar、war或者pom;

  • mvn install 安装,将当前项目安装到本地maven库,供其他项目依赖;

  • mvn deploy部署,在构建环境中完成,复制最终的包到远程库。

执行后面的命令会自动执行前面的命令,比如执行mvn package时会执行validate、clean、compile、test、package五个阶段。

Maven项目构建过程

Maven 核心概念理论

Maven概念模型与依赖解析机制

Maven根据项目的pom.xml文件,把它转化成项目对象模型(POM),这时要解析依赖关系,然后去相对应的maven库中查找所依赖的jar包。在clean,compile,test,package等生命周期阶段都有相应的Plug-in来做这些事情,而这些Plug-in会产生一些中间产物。

Maven概念模型

Maven从仓库解析依赖的机制

当本地仓库没有依赖构件的时候,Maven会自动从远程仓库下载;当依赖版本为快照版本时,Maven会自动找到最新的快照。

  1. 当依赖范围scope=system时,Maven直接从本地文件系统解析构件;

  2. 根据依赖坐标计算仓库路径后,尝试直接从本地仓库寻找构件,若发现构件则解析成功;

  3. 在本地仓库不存在相应构件的情况下,若依赖版本是显式的发布版本构件时,如1.1.0、1.2-alpha-1等,则便利所有的远程仓库,发现后下载到本地仓库并解析使用;

  4. 如果依赖的版本是RELEASE或者LASTEST,则基于更新策略读取所有远程仓库的元数据groupId/artifactId/maven-metadata.xml,将其与本地仓库的对应元数据合并后,计算出RELEASE或者LASTEST的真实值,然后基于真实值检查本地和远程仓库;

  5. 如果依赖版本是SNAPSHOT,则基于更新策略读取所有远程仓库的元数据groupId/artifactId/version/maven-metadata.xml,将其与本地仓库的对应元数据合并后,得到最新快照版本的值,然后基于该值检查本地或者从远程仓库下载;

  6. 如果最后解析到的构件版本是时间戳格式的快照,如1.0-20170712.191220-2,则复制其时间戳格式的文件至非时间戳格式,如SNAPSHOT,并使用该非时间戳格式的构件。

当依赖的版本不明晰的时候,如RELEASE、LASTEST、SNAPSHOT,Maven就需要基于更新远程仓库的更新策略来检查更新。

Maven仓库

构件:在Maven的世界,任何一个依赖、插件或者项目构建的输出,即xxx.jar;任何一个构件都有一组坐标唯一标识。

仓库:得益于坐标机制,任何Maven项目使用任何一个构件的方式都是完全相同的,在此基础上,Maven可以在某个位置统一存储所有Maven项目共享的构件,这个统一的位置就是仓库。

public class DefaultRepositoryLayout
    implements ArtifactRepositoryLayout
{
    private static final char PATH_SEPARATOR = '/';
    private static final char GROUP_SEPARATOR = '.';
    private static final char ARTIFACT_SEPARATOR = '-';
    public String getId()
    {
        return "default";
    }

    public String pathOf( Artifact artifact )
    {
        ArtifactHandler artifactHandler = artifact.getArtifactHandler();

        StringBuilder path = new StringBuilder( 128 );

        path.append( formatAsDirectory( artifact.getGroupId() ) ).append( PATH_SEPARATOR );
        path.append( artifact.getArtifactId() ).append( PATH_SEPARATOR );
        path.append( artifact.getBaseVersion() ).append( PATH_SEPARATOR );
        path.append( artifact.getArtifactId() ).append( ARTIFACT_SEPARATOR ).append( artifact.getVersion() );

        if ( artifact.hasClassifier() )
        {
            path.append( ARTIFACT_SEPARATOR ).append( artifact.getClassifier() );
        }

        if ( artifactHandler.getExtension() != null && artifactHandler.getExtension().length() > 0 )
        {
            path.append( GROUP_SEPARATOR ).append( artifactHandler.getExtension() );
        }

        return path.toString();
    }

    private String formatAsDirectory( String directory )
    {
        return directory.replace( GROUP_SEPARATOR, PATH_SEPARATOR );
    }
}

例如:groupId=com.feiyue、artifactId=demo、version=1.0、artifactId=jdk7、packaging=jar
其对应的路径生成如下:

  1. groupId路径:formatAsDirectory()将groupId中的’.’转换成’/’,com.feiyue就会转换成com/feiyue,之后再加一个’/’,就变成com/feiyue/

  2. artifactId路径:在groupId基础的加上artifactId,再加上一个’/,变成com/feiyue/demo/

  3. version路径:在前面基础上加上version,再加上一个’/,变成com/feiyue/demo/1.0/

  4. 依次加上artifactId、一个’-’、version,就变成com/feiyue/demo/1.0/demo-1.0

  5. 如果有classfier,4)会变成com/feiyue/demo/1.0/demo-1.0-jdk7

  6. 如果extension存在则依次加上’.’、extension。代码中extension是从artifactHandler而非artifact中获取,artifactHandler是由packaging决定的。故packaging决定了构件的扩展名,因此最终的路径为com/feiyue/demo/1.0/demo-1.0-jdk7.jar

Maven仓库的分类

Maven仓库分为两类:本地仓库和远程仓库。当Maven根据坐标寻找构件时,首先会查看本地仓库,若本地仓库存在此构件则直接使用;若本地仓库不存在此构件,Maven就会去远程仓库查找,查找到下载到本地仓库再使用。若本地仓库和远程仓库都没有需要的构件,Maven就会报错。

中央仓库: Maven核心自带的远程仓库,包含了绝大部分开源构件,默认情况,当本地仓库没有Maven需要构件时,就从中央仓库下载。

私服:一种特殊的远程仓库,为节省带宽和时间,应在局域网内架设一个私有仓库服务器,用其代理所有外部的远程仓库。

本地仓库:用户自定义本地仓库的地址,需编辑${user.home}/.m2/setting.xml文件,设置localRepository节点的值为仓库地址即可,默认情况下${user.home}/.m2/setting.xml是不存在的,需要用户从安装目录复制${M2_HOME}/conf/setting.xml文件在进行编辑。

<settings>
<localRepository>E:/maven/repository</localRepository>
</settings>

中央仓库: Maven默认的远程仓库,安装文件中自带了中央仓库的配置,在${M2_HOME}/lib/maven-model-builder-3.2.5.jar中,解压缩找到org\apache\maven\model\pom-4.0.0.xml,可以看到如下默认远程仓库配置:

<repositories>
  <repository>
   <id>central</id>
   <name>Central Repository</name>
   <url>https://repo.maven.apache.org/maven2</url>
   <layout>default</layout>
   <snapshots>
    <enabled>false</enabled>
   </snapshots>
  </repository>
</repositories>

这个配置文件是所有Maven项目都会继承的超级POM.

私服:特殊的远程仓库,架设在局域网内的仓库服务,代理公网的远程仓库,当Maven需要下载构件时,从私服请求,若私服不存在该构件,则从公网远程仓库下载,缓存到私服之后,再为Maven的下载请求提供服务。另外无法从公网仓库下载的构件也能从本地上传到私服供项目使用。

私服优点:节省外网带宽、提供Maven构件速度、部署第三方构件、提供Maven构件稳定性、降低中央仓库负荷。

Maven坐标

唯一标识Maven构件,坐标元素分为groupId、artifactId、version、packaging、classifier.

groupId:必选,定义当前Maven项目隶属的实际项目,不一定是一对一的关系,通常一个实际项目会被划分成很多模块。groupId一般不应该只定义到公司级别,一个公司可能会有很多实际项目,如果groupId只定义到组织级别,那么artifactId只能定义Maven项目。命名方式和Java包名类似,域名反向一一对应。例如:org.springframework.

artifactId:必选,定义实际项目中的一个Maven模块,推荐使用实际项目名称-模块名称,这样便于找到某个项目的一组构件。例如:spring-core,spring-beans,spring-web等。

version:必选,定义Maven项目当前所处的版本。例如:4.3.9.RELEASE、1.0-SNAPSHOT、RELEASE、LATEST、2.1等。

packaging:可选默认是jar,定义Maven项目的打包方式。打包方式有jar、war、pom等。

classifier:不能直接定义,帮助定义构建输出的一些附属构件。附属构件与主构件对应,例如-javadoc.jar、-sources.jar附属构件包含了java文档和源代码。

依赖管理

依赖管理分为传递性依赖、依赖调解、可选依赖、排除依赖、归类依赖等。

传递性依赖

maven模块 -> spring-jdbc -> spring-core -> commons-logging

假设: A -> B -> C,即A对B是第一直接依赖,B对C是第二直接依赖,A对C是传递性依赖,第一直接依赖(简称F)和第二直接依赖(简称S)的范围决定了传递性依赖(简称T)的范围。如图所示:

传递性依赖

例如:A -> B -> C,A依赖B的范围是test,B依赖C的范围是compile,则A传递依赖C的范围是test。

结论:当S=compile时,T与F的范围一致;当S=test时,依赖不会传递;当S=provided时,只有当F=provided时,T=provided;当S=runtime时,T=F,但F=compile例外,此时T=runtime.

依赖调解

依赖调解第一原则:路径最近者优先。

例如:A -> B -> C -> X1 长度为3 A -> D -> X2 长度为2,因此X2会被解析使用
依赖调解第二原则:第一原则优先,依赖路径相等时,POM中依赖声明顺序靠前的优先。

例如:A -> B -> X1 长度为2 A -> C -> X2 长度为2,但是POM文件中B的依赖声明靠前,因此X1会被解析使用。

可选依赖

A依赖于B,B依赖于X和Y,B对于X和Y的依赖都是可选依赖,即optional=true

AB、BX(可选)、BY(可选)。可选依赖不会传递,即X、Y对A没有影响。

可选依赖一般是多种互斥的特性,具体使用时只选其一。

可选依赖

排除依赖

使用exclusions元素声明排除依赖,exclusions包含一个或者多个exclusion子元素,因此可以排除一个或者多个传递性依赖。注意声明exclusion时只需要groupId和artifactId,而不需要version元素,因为只需要groupId和artifactId就可以唯一定位依赖图中的某个依赖。

排除依赖

归类依赖

spring的依赖包版本都是相同的,可以使用properties元素定义Maven属性spring.version=4.x

在定义依赖时可以使用美元符号加大括弧环绕的方式来引用Maven属性,例如${spring.version}。

聚合与继承

聚合:多个项目或者模块聚合到一起,建立一个package方式为pom的项目parent专门负责聚合工作,并使用modules-module指定子模块,目的是快速构建项目。

继承:多个模块聚合时,子模块需要继承父模块以消除重复配置。

聚合与继承的共同点是聚合POM与继承关系中的父POM的packaging都必须是pom。

聚合关系与继承关系的比较如下图所示:

聚合与继承

四种 Maven 项目创建方式

手动方式构建

Maven项目由一个自己默认的配置,使用者不需要修改那些约定的内容,这就是“约定优于配置”,按照Maven项目目录约定,手动创建各个文件夹即可,一般不会使用这种方式。

动态web的Maven项目的目录约定如下图所示:

Maven项目目录约定

命令行

本地磁盘建立一个空目录C:/maven/hello,命令行进入到hello目录,执行下面的命令
mvn archetype:generate -DgroupId=com.cloud.hellomaven -DartifactId=hellomaven-service -Dversion=1.0.0-SNAPSHOT -Dpackage=com.cloud.service

执行成功的话会自动在hello中创建符合maven项目约定的目录结构。

说明:

archetype:generate:生成maven项目骨架。

  • DgroupId指定maven坐标的groupId

  • DartifactId指定maven坐标的artifactId

  • Dversion指定maven坐标的version

  • Dpackage指定maven项目的src下的包名

自动创建的maven项目结构如下:

自动创建的maven项目结构

Eclipse IDE

Eclipse提供了一个很好的插件m2eclipse无缝将Maven和Eclipse集成在一起,配置插件选择本地maven目录和配置文件setting.xml即可。

点击Eclipse菜单栏File->New->Ohter->Maven,选择Maven Project,一路默认Next,有一步需要填写Group Id、Artifact Id、Version、选择打包方式Package(jar、war、pom),选择编译环境即可。

New Maven Project

完成后目录结构如下:

Eclipse创建的Maven项目结构

Idea IDE

Idea IDE是一款很不错的开发Maven项目的IDE,创建一个maven web项目的过程如下:

选择File-New-Project,选择Maven,勾选Create from archetype,选择maven-archetype-webapp,

New Maven Project

点击Next,填写Group Id、Artifact Id、Version三项,

Group Id、Artifact Id、Version坐标

点击Next,选择Maven home,选择setting file,

Maven Home

点击Next,填写Project name,选择项目路径即可,

Project name

Finish完成maven web项目创建。

Setting文件配置与POM 文件解析

Setting文件配置

配置用户范围和全局范围的setting.xml

全局范围: ${maven.conf}/settings.xml文件可以全局定制Maven的行为,对一台机器上的所有用户有效。

用户范围: ${user.home}/.m2/settings.xml,只有当前用户才会受到该配置影响,还便于Maven的升级,Maven升级新版本时不需要触动该文件,推荐配置用户范围。

设置HTTP代理

公司网络需要通过安全认证的代理访问因特网,这种情况下需要为Maven配置HTTP代理,才能正常访问外部仓库下载所需要的资源。

在settings.xml文件中添加代理配置。

<proxies>    
   <proxy>    
     <id>myproxy</id>    
     <active>true</active>    
     <protocol>http</protocol>    
     <host>192.0.0.100</host>    
     <port>1234</port>    
     <username>xxxxx</username>    
     <password>xxxxx</password>    
     <nonProxyHosts>*.xxx.com|xxx.org</nonProxyHosts>    
   </proxy>    
</proxies>  

proxies下可以添加多个proxy节点,默认第一个active为true的会生效。

nonProxyHost表示不需要代理访问的地址。中间的竖线分隔多个地址,此处可以使用星号作为通配符号。

远程仓库的认证

一些远程仓库出于安全考虑需要提供用户名、密码进行认证才能访问,这时需要配置认证信息,认证信息必须配置到setting.xml文件中,只放在本机,其他成员不可见,在setting.xml文件中添加server配置,一个servers可以配置一个或者多个server,假设一个id为feiyue-repo的仓库配置认证如下:

<servers>
  <server>
   <id>feiyue-repo</id>
   <username>repo-username</username>
   <password>repo-pwd</password>
  </server>
</servers>

setting.xml文件中server元素的id必须与pom.xml文件中需要认证的repository元素的id完全一致。

镜像

如果仓库X可以提供仓库Y存储的所有内容,则X可以被称为Y的一个镜像。镜像往往能够提供比中央仓库更快的服务,配置Maven使用镜像来代替中央仓库,编辑setting.xml文件。

<mirrors>
 <mirror>
      <id>jboss-public-repository-group</id>
      <mirrorOf>central</mirrorOf>
     <name>JBoss Public Repository Group</name>  <url>http://repository.jboss.org/nexus/content/groups/public</url>
 </mirror>
</mirrors>

mirrorOf:值为central,表示该配置为中央仓库的镜像,任何对于中央仓库的请求都会转至该镜像;

id:是远程仓库的唯一标识。

name:阅读方便可自定义的名称。

url:远程仓库的地址。

如果需要认证,基于该id配置仓库认证。

mirrorOf取值如下:

*:匹配所有远程仓库

external:*匹配所有远程仓库,使用localhost的除外,使用file://协议的除外,即匹配不在本机上的远程仓库;

rep1,rep2:匹配id=rep1和id=rep2的仓库,使用逗号分隔多个远程仓库;

*,!rep2:匹配所有远程仓库,rep2除外,使用感叹号将仓库从匹配中排除。

POM文件常用配置解析

parent父项目配置

<parent>
    <groupId>com.feiyue.parent</groupId>
    <artifactId>feiyue-parent</artifactId>
    <version>1.0-SNAPSHOT</version>
    <relativePath>../pom.xml</relativePath>
</parent>

project根节点下配置parent节点指定继承的父项目坐标,groupId、artifactId、version必选,唯一标识父项目,relativePath:可选,父项目的pom.xml文件的相对路径,默认值是../pom.xml.

Maven首先在当前构建项目的地方寻找父项目的pom,其次在本地文件系统的relativePath位置,然后在本地仓库,最后在远程仓库寻找父项目的pom.

dependency依赖配置

<dependency>
<groupId>xx</groupId>
<artifactId>yy</artifactId>
<version>x.x</version>
<scope> </scope>
<type></type>
<optional></optional>
<exclusions>
  <exclusion></exclusion>
</exclusions>
</dependency>

groupId、artifactId、version必选,依赖的基本坐标,找到需要的依赖。

type:依赖的类型,对应于项目坐标中定义的packaging,该元素不必声明默认为jar.

scope:依赖的范围

Maven在编译项目主代码时使用一套classpath,主代码中使用到的其他jar以依赖被引入到classpath中;Maven在编译和执行测试的时候会使用另外一套classpath;实际运行Maven项目的时候,又会使用一套classpath。故Maven项目依赖范围就是控制依赖于三种classpath(编译classpath、测试classpath、运行classpath)的关系。

Maven依赖范围有以下几种:

compile:编译依赖范围,没有指定默认使用该依赖范围。对于编译、测试、运行三种classpath都有效。例如:spring-core。

test:测试依赖范围,只对测试classpath有效,在编译主代码或者运行项目是无法使用。例如:junit。

provided:已提供依赖范围,对于编译和测试classpath有效,运行时无效。例如:servlet-api

runtime:运行时依赖范围,对于测试和运行classpath有效,但在编译主代码时无效。例如:spring-jdbc。

system:系统依赖范围,和provided作用一致。但是system范围的依赖时必须通过systemPath元素显示第指定依赖文静的路径。由于该类依赖不是通过Maven仓库解析的,而且往往与本机系统绑定,可能造成不可抑制,应谨慎使用。

import:只使用在dependencyManagement中,表示从其他的pom中导入depency的配置,不会对三种classpath产生实际的影响。

Maven依赖范围

optional:标记依赖是否可选

exclusions:用来排除传递性依赖

pluginManagement默认插件配置

配置到project-build节点中,配置供子项目引用的插件。

<!--子项目可以引用的默认插件信息。该插件配置项直到被引用时才会被解析或绑定到生命周期。给定插件的任何本地配置都会覆盖这里的配置-->
<pluginManagement>
    <!--使用的插件列表-->
    <plugins>
        <!--plugin元素包含描述插件所需要的信息-->
        <plugin>
            <!--插件在仓库里的groupId-->
            <groupId></groupId>
            <!--插件在仓库里的artifactId-->
            <artifactId></artifactId>
            <!--被使用的插件的版本-->
            <version></version>
            <!--是否从该插件下载Maven扩展(例如打包和类型处理器)默认为false,由于性能原因,只有在真需要下载时,该元素才被设置成true。-->
            <extensions></extensions>
            <!--在构建生命周期中执行一组目标的配置。每个目标可能有不同的配置。-->
            <executions>
                <!--execution元素包含了插件执行需要的信息-->
                <execution>
                    <!--执行目标的标识符,用于标识构建过程中的目标,或者匹配继承过程中需要合并的执行目标-->
                    <id></id>
                    <!--绑定了目标的构建生命周期阶段,如果省略,目标会被绑定到源数据里配置的默认阶段-->
                    <phase></phase>
                    <!--配置的执行目标-->
                    <goals></goals>
                    <!--配置是否被传播到子POM-->
                    <inherited></inherited>
                    <!--作为DOM对象的配置-->
                    <configuration></configuration>
                </execution>
            </executions>
            <!--项目引入插件所需要的额外依赖-->
            <dependencies>
                <!--参见dependency元素配置-->
                <dependency>
                </dependency>
            </dependencies>
            <!--任何配置是否被传播到子项目-->
            <inherited></inherited>
            <!--作为DOM对象的配置-->
            <configuration></configuration>
        </plugin>
    </plugins>
</pluginManagement>

repositories远程仓库的配置

很多情况默认的中央仓库无法满足项目需求,需要配置其他远程仓库,如JBoss Maven库,需要在Pom.xml文件中配置。

<repositories>
 <repository>
  <id>jboss-maven2-release-repository</id>
  <name>JBoss Repository</name>
  <url>http://repository.jboss.org/maven2/</url>
  <releases>
   <enabled>true</enabled>
   <checksumPolicy>ignore</checksumPolicy>
   <updatePolicy>daily</updatePolicy>
  </releases>
  <snapshots>
   <enabled>false</enabled>
   <checksumPolicy>fail</checksumPolicy>
   <updatePolicy>always</updatePolicy>
  </snapshots>
  <layout>default</layout>
 </repository>
</repositories>

在repositories元素下可以声明一个或多个远程仓库。

id:任何一个仓库声明的id必须是唯一的,Maven自带中央仓库id为central,如果其他仓库声明id也是central,就会覆盖中央仓库的配置。

url:指向仓库的地址,一般该地址是基于http协议,用户可以浏览器中打开仓库地址浏览构件。

releases:支持发布版本下载。

snapshots:支持快照版本下载,enabled=true时开启releases和snapshots还有2个子元素。

checksumPolicy:配置Maven检查检验和文件的策略。当构建被部署到仓库中时,会同时部署对应的校验和文件,在下载构件的时候,Maven会验证校验和文件,如果校验和验证失败,会根据checksumPolicy的值进行选择。默认值是warn-Maven会在执行构建时输出警告信息,可用值还有fail-Maven遇到校验和错误时就让构建失败;ignore-使Maven完全忽略校验和错误。

updatePolicy:配置Maven从远程仓库检查更新的频率,默认值是daily。可用值有daily-每天检查一次、always-每次构建都会检查更新、interval:X-每个X分钟检查一次更新、never-从不检查更新。
layout:值为default表示仓库的布局是Maven2及Maven3的默认布局。

用 nexus 搭建 Maven 私服

Nexus私服搭建与配置

Nexus软件下载与安装

下载地址:http://www.sonatype.org/nexus/archived/

Nexus安装启动与使用

公司内部大部分人的电脑不能访问公网,不能从maven的中央仓库下载依赖,因此找一台有公网权限的机器搭建nexus私服,其他项目组人员连接到这个私服上即可。1.节省了下载jar包依赖的过程,不必每个人都去下载jar包的依赖

软件准备:jdk1.7、maven-3.5.0、Nexus 2.12.0-01

Nexus 2.12.0-01下载

Nexus 2.12.0-01下载

Windows平台下载zip格式 下载nexus-2.12.0-01-bundle.zip解压到本地磁盘

D:\develop\nexus\nexus-2.12.0-01

在D:\develop\nexus\nexus-2.12.0-01\bin\jsw目录下有很多不同的操作系统版本,我的系统是Win7 64位,选择windows-x86-64目录。

windows-x86-64目录说明

windows-x86-64目录说明

console-nexus.bat:命令行方式启动nexus服务器,窗口关闭不会注册为windows服务

install-nexus.bat:将nexus安装成windows服务,开机时自动启动

start-nexus.bat:启动nexus服务,也可以直接在管理-服务中手动启动nexus服务

stop-nexus.bat:停止nexus服务

uninstall-nexus.bat:卸载nexus服务

wrapper.exe:

配置环境变量

NEXUS_HOME= D:\develop\nexus\nexus-2.12.0-01

Path= ;%NEXUS_HOME%\bin\jsw\windows-x86-64

上述步骤成功后,nexus即安装成功,启动服务,在浏览器中访问

http://localhost:8081/nexus/

默认的用户名是 admin 密码是 admin123

Nexus首页

到此nexus安装成功。

Nexus用户管理

选择Security-Users添加用户User ID:feiyue 密码:feiyue

添加用户

填写基本信息,添加角色,选择Nexus Administrator Role管理员角色。

管理员角色

为Nexus配置代理服务器

如果机器通过配置代理才能访问外网,Nexus可以配置代理服务器,选择Administration-Servers,找到如下配置,填写代理信息。

配置代理服务器

如果Nexus私服所在机器可以直接访问外网,则可以省略这一步 。

配置repository

在Views/Reposities中选择Reposities进行配置

Nexus可以配置3种类型的仓库,分别是proxy、hosted、group

Proxy:远程仓库的代理,比如nexus中配置了一个中央仓库的proxy,当用户向这个proxy请求一个
artifact时,proxy现在本地查找、如果找不到就到远程的中央仓库下载,起到了一个中转的作用。

配置中央库proxy:

需要做的就是把Download Remote Indexes改为true,这样nexus才会从central repository下载索引,才能在nexus中使用artifact search的功能。

配置repository

Hosted:宿主仓库,用户可以把自己的一些构件部署到hosted中,也可以手动上传到hosted中。比如Oracle的驱动程序ojdbc6.jar在中央仓库找不到,就需要手工上传到hosted中。

配置hosted repository:一般会配置3个hosted repository,分别是3rd party、Snapshots、Releases,分别用来保存第三方jar(典型的比如ojdbc6.jar),项目组内部的快照、项目组内部的发布版

只是Deployment Policy这个选项,一般Snapshots会配置成允许,而Releases和3rd party会设置为禁止

Hosted宿主仓库

Group:仓库组,在maven中没有这个概念,是nexus特有的。目的是将上述多个仓库聚合,对用户暴露统一的地址,用户就不必在pom中配置多个地址了,只要统一配置group即可。

配置group repository

group其实是一个虚拟的仓库,通过对实体仓库(proxy、hosted)进行聚合,对外暴露一个统一的地址 ,注意放到左边的仓库,才是会被聚合的仓库

配置group repository

仓库搜索服务

常见的几个功能强大的公共Maven仓库搜索服务。

Sonatype Nexus

地址:https://repository.sonatype.org/

Nexus是当前最流行的开源Maven仓库管理软件,提供了关键字搜索、类名搜索、坐标搜索、校验等功
能。

Mvnrepository

地址:http://mvnrepository.com/

界面友好,提供基于关键字的搜索、构件下载、依赖声明代码片段。

中央仓库检索服务

地址:http://search.maven.org/

多模块项目构建实战

本章节给出一个含有父项目parent以及一个多模块项目的空框架做为一个maven项目构建的一个实例,该项目的源码我放到了了github上:

github地址:https://github.com/liangpengju/maven_dev

框架中只是展示Maven多模块项目构建的一种方式,没有具体的代码实现,后续有时间会给出一个demo,这里仅供参考交流。

包括了2个项目,一个是parent聚合项目,另外一个是后台管理分模块分层的项目,结构如下图所示。

maven_dev

maven_dev中包含父聚合项目gseem-parent,没有实际的内容,主要是pom.xml文件中集中定义依赖版本号、依赖包管理、插件管理、插件等可以继承的元素。

gseem-manage是一个多模块的聚合项目,包括4个子模块,parent都是gseem-manage

gseem-manage-pojo是项目实体类模块,打包方式为jar

gseem-manage-mapper是项目数据库操作dao模块,对应于mybatis的mapping中的xml文件,打包方式为jar,依赖于gseem-manage-pojo模块

gseem-manage-service是项目业务逻辑服务模块,包括接口和实现,打包方式为jar,依赖于gseem-manage-mapper模块

gseem-manage-web是项目的静态资源、jsp动态页面模块,包括接口和实现,打包方式为jar,依赖于gseem-manage-service模块

这个项目框架做到了依赖库的统一版本管理,分层代码的复用等。

总结

Maven主要服务于基于Java平台的项目构建、依赖管理和项目信息管理的优秀工具。 本文主要从以下几个方面来对Maven工具的使用进行了讲解:

  • Maven基础环境配置与Maven常用的基本命令。

  • Maven相关的核心概念理论:概念模型、仓库、坐标、依赖管理、聚合与继承。

  • 4种Maven项目的创建方式:手动创建、命令行、Eclipse IDE、Idea IDE.

  • POM文件常用配置解析与Setting文件常用配置解析。

  • 使用Nexus搭建Maven私服与仓库搜索服务。

  • 多模块项目构建实战。

Maven 还有很多其他的功能,因时间和篇幅有限,可以后续进行探讨。


实录:《梁朋举: Maven 项目的构建与管理实战解析》


彩蛋

重磅 Chat 分享:《一场 Chat 让你搞清 BAT 程序员的技术职级》

分享人:
胜洪宇,一线互联网公司前端技术组长,掘金签约作者,前端博客博主,所讲课程帮助超过20万前端小伙伴学习。
Chat简介:
很多程序员向往进入 BAT 这样的大型互联网公司,但是又不知道他们如何评定技术职级。
- 阿里集团薪资职级如何划分?让你快速得到马云的青睐。
- 在百度明白这些,你将快速晋升。
- 腾讯职级里的小秘密,这样工作你会更强。
一场 Chat 让你搞清 BAT 的技术评价体系,为您进入超级互联网公司指明技术方向,时刻做好准备!如果您希望您的技术团队也像这些互联网巨头一样强大,本场 Chat 我将帮您马上模仿建立有效的技术职级体系。

想要免费参与本场 Chat ?很简单,「GitChat技术杂谈」公众号后台回复「BAT」

这里写图片描述

2
0

查看评论
* 以上用户言论只代表其个人观点,不代表CSDN网站的观点或立场
    个人资料
    • 访问:82616次
    • 积分:1538
    • 等级:
    • 排名:千里之外
    • 原创:8篇
    • 转载:0篇
    • 译文:0篇
    • 评论:109条
    文章存档