Maven

1、Maven的介绍与安装

1.1 Maven简介

Maven的英文翻译为“专家”,“内行”。Maven是Apache下一个纯Java开发的开源项目,它是一个跨平台的项目管理工具,即针对Java平台的项目构建和依赖的管理。Maven提供了开发人员构建一个完整的生命周期框架,从清理、编译、测试、报告、打包、再到最后的部署。简单来说Maven就方便Java项目的构建,同时也方便开发者对项目的管理。

Maven在企业中使用非常的广泛,虽然用的很多,但是有些人对于Maven的发音任然不标准。Maven 读音是 [ˈmeɪvn]。可以读作“霉文”或者”麦文”,但是不能读成”妈文”、”某文”等。

(1) 项目构建

我们首先要区别的是,项目构建并不是项目创建的意思,项目创建只是一个工程的创建过程,而项目构建过程包括:【清理→编译→测试→报告→打包→部署】这几个步骤,这六个步骤就是一个项目的完整构建过程。

image

(2) 依赖管理

依赖指的是项目与jar包之间的相互依赖,比如我们在使用Spring框架的时候,需要用到Spring依赖的jar包。而依赖管理指的就是使用Maven来管理项目中使用到的jar包,Maven管理的方式就是“自动下载项目所需要的jar包,统一管理jar包之间的依赖关系”。比如在文件上传的时候,光光有common-fileupload这个jar包是不行的,common-fileupload还依赖于common-io这个包jar包,此时由于Maven的依赖管理机制,都会帮我们自动下载这些包,我们并不需要管。

image

1. 2 为什么使用Maven

为什么使用Maven我们首先得去分析传统项目管理的缺陷有哪些:

  1. jar包需要我们自己去网上下载,非常的麻烦,而且有些jar包根本找不到。
  2. 如果某个jar需要依赖其它jar包的话,还需要去找依赖的jar包,而且很有可能我们漏掉了某个依赖关系,就会导致项目运行报错。
  3. 没有对jar包的版本统一管理,容易导致版本冲突。
  4. 传统的一个项目就是一个工程。如果项目比较庞大,那么利用包名来划分模块,显然容易造成混淆而且不利于分工合作。
  5. 传统项目的部署和迁移不方便,容易出现错误。

根据以上缺陷便可以总结出使用Maven的好处:

  1. 避免四处找jar包。
  2. 消除Jar包之间的相互依赖。
  3. 避免Jar包冲突
  4. 项目拆分多个模块。
  5. 项目的步署和迁移方便,甚至分步式部署也很方便。

1.3 Maven的下载

Maven的下载地址为:https://maven.apache.org/download.cgi

image

点击apache-maven-3.6.3-bin.zip下载。这里当然选择的是最新的版本,下载成功之后,在电脑上解压。

解压后的文件目录如下所示:

image

下面介绍一下各个文件的作用:

  1. bin目录:包含 maven运行时的脚本, 这些脚本用来配置Java命令,准备好 classpath和相关的java系统属性。 其中:mvn 是UNIX平台的shell脚本, mvn.cmd 是Windows平台的 bat脚本, mvcDebug 是UNIX的调试脚本, mvcDebug.cmd 是Windows平台的 调试脚本。
  2. boot目录:包含两个文件。 其中plexus-classworlds-2.6.0.jar ,是一个类加载器框架。Maven可以使用它,来加载自己的类库。
  3. conf目录:是配置文件目录,其中有一个 settings.xml 文件,用来配置maven。还有一个 logging文件,日志记录,来配置日志的相关信息。
  4. lib目录:maven运行时,所需要的类库。 里面放置了大量的 .jar 类库及对应的软件许可证 .license.
  5. LICENSE:Maven使用的软件许可证。
  6. NOTICE:Maven包含的第三方软件
  7. README.txt:Maven的简单介绍,包括安装需求和安装的简要指令。

我们光下载了Maven的文件是不行的,还得配置全局变量,下面是对Maven的配置。

1.4 Maven的配置

注意:Maven是依赖于JDK的,所以我们在安装 Maven之前,电脑上必须先安装 JDK。

首先右击此电脑—>属性—>高级系统设置—>高级—>环境变量。

image

①、新建系统变量:MAVEN_HOME。变量值:D:\Maven\apache-maven-3.6.3(这是你Maven的存储路径)

image

②、编辑系统变量:Path。添加变量值:%MAVEN_HOME%\bin。其中“%MAVEN_HOME%\bin”代表的就是”D:\Maven\apache-maven-3.6.3\bin“目录。

image

③、检验配置是否成功:用win键+R,输入cmd进入dos命令,输入mvn -v,出现如下信息则表明成功!

image

④、配置运行参数环境变量(可选配置):MAVEN_OPTS。变量值:-Xms128m -Xmx512m。

image

因为Maven使用来Java来启动的,所以依赖于JVM。所以可以通过JAVA命令参数的方式来设置MAVEN运行参数。

1.5 Maven的优化

①、修改本地仓库位置。

Maven管理的jar包默认是存储在C盘用户目录下的 .m2 下的repository中。

image

如果你和我一样有强迫症的话(不喜欢把无关系统的东西放在C盘),可以更改Maven的存储位置。

首先我们找到解压的Maven文件,然后打开conf目录下的setting.xml。

大概在55行左右我们加入如下配置文件:

<localRepository>D:/Maven/maven-repository</localRepository>

我把它存放在D盘下。

image

②、修改镜像源。

Maven默认下载jar包是从中央仓库下载的,所以我们在国内下载jar包是非常非常的慢,所以我们需要改一下,这里推荐阿里云的仓库。

大概在setting.xml中的第159行左右我们加入如下配置文件:

<mirror>
    <id>nexus-aliyun</id>
    <name>nexus-aliyun</name>
    <url>http://maven.aliyun.com/nexus/content/groups/public</url>
    <mirrorOf>central</mirrorOf>
</mirror>

image

③、修改Maven默认的JDK版本。

我们在使用编辑软件开发时,编辑软件总是默认给我们设置奇奇怪怪的JDK版本,导致程序总是莫名的报错,这一点我是采过坑的。自己电脑上安装的什么版本的JDK我们就设置对应的JDK版本就可以了。

大概在setting.xml中的第218行左右我们加入如下配置文件:

<profile>
    <id>jdk-1.8</id>
    <activation>
        <jdk>1.8</jdk>
        <activeByDefault>true</activeByDefault>
    </activation>
    <properties>
        <maven.compiler.source>1.8</maven.compiler.source>
        <maven.compiler.target>1.8</maven.compiler.target>
        <maven.compiler.compilerVersion>1.8</maven.compiler.compilerVersion>
    </properties>
</profile>

我的是JDK1.8版本。

image

2、在Eclipse和IDEA中集成Maven

在上一章的Maven中,介绍了Maven的配置,那么接下来我们就可以在开发工具中使用它了。目前常用的开发工具有Eclipse、IDEA。虽然它们自身都集成了一个Maven,但自带的Maven版本很低,所以通常我们使用自己配置好的Maven,不用自带的。

2.1 在Eclipse中集成Maven

①、在Eclipse指定Maven的位置

打开Eclipse后,选择Windows—>Preference—>Maven—>Installations 。

image

②、指定conf/settings.xml的位置,从而指定Maven本地仓库的位置

image

注意:如果报错Could not read settings.xml。原因是:maven的setting.xml文件内有不合法字符,将其删除或修改即可。

这样在Eclipse中配置Maven就已经完成了,然后我们就可以在Eclipse中创建我们的Maven项目了,这里就不用Eclipse创建了,后面会使用IDEA举例。

2.2 在IDEA中集成Maven

首先【File—>Settings—>Build,Execution,Deployment—>Build Tools—>Maven】。按照如下图操作:

image

然后我们再勾选一个地方。此处勾选的作用是,当修改pom文件时,Maven就会自动帮我们导包了。

image

这样IDEA中配置Maven就成功啦,然后下面我们用IDEA来创建Maven项目。


注意:上面这种方式设置的Maven是相对于当前项目而言的,如果再创建一个Maven项目可能又要配置Maven,所以我们要配置IDEA全局的Maven。(这个配置是可选,如果不嫌麻烦倒是可以设置一下)

①、【File—>Close Project】,我们找到界面右下角的Configure。然后【Project Defualt—>Settings】。

image

②、然后其它配置就是一样的了。

image

3、Maven项目的目录结构

我们既然使用的是Maven工具来构建我们的项目,所以在创建项目时,一定要遵守Maven的规则,只有符合Maven的规定才属于一个Maven项目。

Maven项目的目录结构规范如下:

  hellomaven ——项目名称
    | –src ——源文件
    | -----main ——存放主程序
    | ----------java ——存放项目的.java文件
    | ----------resources ——存放项目资源文件,如spring, hibernate配置文件
    | -----test ——存放测试程序
    | ---------java ——存放所有单元测试.java文件,如JUnit测试类
    | ---------resources ——测试资源文件

    | --target ——项目输出位置,编译后的class文件会输出到此目录
    | --pom.xml ——maven项目核心配置文件

下图是用IDEA创建的普通Maven项目:

image

我们使用maven项目来管理所依赖的jar包,就不需要手动向工程添加jar包,只需要在pom.xml文件(maven工程的配置文件)添加jar包的坐标即可,它就会自动从maven仓库中下载jar包、运行。所以pom(Project Object Model)文件是Maven项目最最最核心的地方。后面会有详细的介绍。

2.4 IDEA中使用Maven创建Web项目

①、首先在界面的左上角点击【File-->New-->Project】会出现下面的界面。

注意:【Creater from archetype】选项前面一定要打勾。如果是普通的Java项目则直接Next即可。

然后一定要选择【maven-archetype-webapp】,别选择其它的了,否则就不是一个Web项目了。

image

②、填写GroupId和ArtifictId

这里的GroupId一般写公司名(例如我的:com.thr),ArtifictId一般写项目名。

image

③、配置自己的maven,然后Next

如果这里是默认的我们就配置一下我们自己的Maven。

image

④、点击Finish完成创建

image

第一次使用Maven创建一个Web项目,Maven会给我们下载很多的插件。我们耐心等待它下载完毕即可。

创建后的项目目录如下:

image

可以发现并没有像Maven目录约定的那样,没有src/mian/java、src/main/resourece和test这些文件。这是因为创建了一个Web项目,IDEA可能比较“懒”,只给我们创建了webapp目录,并没有给我们创建java和resources,不是说IDEA是非常懂我们Java程序员的吗?为什么这会儿就不懂了呢!所以呢我们必须要自己创建。也许是我用的IDEA版本有点老了吧(我的是2018年的版本),不知道最新的版本解决这个问题了没有。

点击【File—>Project Structure—>Modules】或者快捷键【Ctrl+Shift+Alt+S】。

image

创建之后要把java文件和resources文件改成相应的类型:

  • java改成Sources类型
  • resources改成Resources类型

GIF 2020-6-5 17-03-45

创建test文件也是一样的,这里就不创建了。

然后将项目部署到Tomcat测试运行就可以了。

在创建项目时,一定要遵守这些规则,这些约定,只有符合这样约定的结构,才属于Maven 结构

3、Maven的生命周期和常用命令

3.1 Maven的生命周期

Maven的生命周期就是对所有的构建过程进行抽象和统一。包含了项目的清理、初始化、编译、测试、打包、集成测试、验证、部署和站点生成等几乎所有的构建步骤。Maven有三套相互独立的生命周期,分别是clean、default和site。其中每个生命周期都包含一些阶段(phase),阶段是按顺序执行的,且后面的阶段依赖于前面的阶段。执行某个阶段时,其前面的阶段会依顺序执行,但不会触发另外两套生命周期中的任何阶段。

Maven的三套生命周期:

  1. clean生命周期(项目清理生命周期):对在进行构建之前进行的一些清理工作。clean
  2. default生命周期(默认生命周期):构建的核心部分,编译、测试、打包、安装、部署等等。compile test install package
  3. site生命周期(生成站点生命周期):生成项目报告,站点,发布站点。site

注意:由于这三个阶段的生命周期都是相互独立的,所以不能看成一个整体。但可以同时直接运行 mvn clean install site 这三套生命周期。下面我们分别来谈谈这三个生命周期。

因为Maven的生命周期是抽象的,所以生命周期不做任何实际的工作,实际任务由插件来完成。

3.2 Clean生命周期(Clean Lifecycle)

Clean Lifecycle 对在进行构建之前进行的一些清理工作。

Clean生命周期一共包含了三个阶段:

  1. pre-clean:执行一些需要在clean之前完成的工作
  2. clean:移除所有上一次构建生成的文件
  3. post-clean:执行一些需要在clean之后立刻完成的工作

3.3 Default生命周期(Default Lifecycle

Default Lifecycle是构建的核心部分,编译,测试,打包,部署等等,Default生命周期是Maven生命周期中最重要的一个,绝大部分工作都发生在这个生命周期中。

其中一些比较重要和常用的阶段:

  • validate:验证项目的正确性。
  • initialize:初始化构建状态,比如设置属性值。
  • generate-sources:生成包含在编译中的源代码。
  • process-sources:处理源代码。
  • generate-resources:生成源代码所需的资源。
  • process-resources:复制并处理资源文件,至目标目录。
  • compile:编译项目的源代码。
  • process-classes:处理编译后生成的文件,如字节码增强或扩展。
  • generate-test-sources:生成测试源代码。
  • process-test-sources:处理测试源代码。
  • generate-test-resources:生成测试所需的资源文件。
  • process-test-resources:复制并处理资源文件,至目标测试目录。
  • test-compile:编译测试源代码。
  • process-test-classes:处理编译后生成的测试文件。
  • test:使用合适的单元测试框架运行测试,这些测试代码不会被打包或部署。
  • prepare-package:准备打包。
  • package:接受编译好的代码,打包成可发布的格式,如 JAR ,WAR。
  • pre-integration-test:执行集成测试之前的准备工作。
  • integration-test:集成测试。
  • post-integration-test:集成测试后继续操作。
  • verify:检查包是否有效。
  • install:将包安装至本地仓库,以让其它项目依赖。
  • deploy:将最终的包复制到远程的仓库,以让其它开发人员与项目共享。

注意:在一个生命周期中,当运行某个阶段的时候,它之前的所有阶段都会被运行,而且不需要额外去输入前面的阶段。下面举例说明一下:

①、执行mvn clean:调用clean生命周期的clean阶段,实际执行pre-clean和clean阶段。

②、执行mvn test:调用default生命周期的test阶段,实际执行test以及之前所有阶段。

③、执行mvn clean install:调用clean生命周期的clean阶段和default的install阶段,实际执行pre-clean和clean,install以及之前所有阶段。

然后下面举第②个例子:执行mvn test。

在IDEA中执行test命令:

image

前面说了Maven的命令是有各自对应的插件去完成。我们看到红色框的部分,有三个不同类型的Plugin。第一个maven-resources-plugin:3.0.2是用来处理资源文件的,第二个maven-compiler-plugin:3.8.0是用来编译文件的。第三个maven-surefire-plugin:2.22.1是用来测试文件的。它们的具体会在后面介绍。

3.4 Site生命周期(Site Lifecycle)

Site Lifecycle 生成项目报告,站点,发布站点,站点的文档(站点信息,依赖..)。

Site生命周期,生成站点信息四个阶段:

  • pre-site:执行一些需要在生成站点文档之前完成的工作

  • site:生成项目的站点文档

  • post-site:执行一些需要在生成站点文档之后完成的工作,并且为部署做准备

  • site-deploy:将生成的站点文档部署到特定的服务器上

这里经常用到的是 site 阶段和 site-deploy 阶段,用来生成和发布 maven 站点,这是 Maven 比较强大的功能,文档及统计数据自动生成。由于现在的系统会有专门工具来生成文档或报表。所以这个功能也是比较鸡肋吧,不够简洁和美观,用的不太多。

3.5 Maven中常用命令

通过上面对maven的生命周期的分析,可以总结出maven中常用的命令有:clean、compile、test、package、install。所以下面我们讲讲这几个常用的 Maven 命令。首先我们先创建一个Maven项目。并且在里面添加一些代码用来测试。

image

在 src/main/java新建类 HelloMaven.java:

package com.thr;

/**
 * @author tanghaorong
 * @date 2020-06-09
 * @desc 主代码
 */
public class HelloMaven {

    public String hello(String name){
        return name;
    }
}

在 src/test/java新建中创建测试类 TestMaven.java

package com.thr;

import org.junit.Assert;
import org.junit.Test;

/**
* @author tanghaorong
* @date 2020-06-09
* @desc 测试代码
*/
public class TestMaven {
    @Test
    public void testHello(){
        HelloMaven helloMaven = new HelloMaven();
        String name = helloMaven.hello("唐浩荣");
        //比较输入参数是否同
        Assert.assertEquals("唐浩荣",name);
    }
}

pom.xml 文件引入JUnit依赖如下:

<dependency>
    <groupId>junit</groupId>
    <artifactId>junit</artifactId>
    <version>4.11</version>
    <scope>test</scope>
</dependency>

①、clean:将之前编译的文件删除。

我们首先运行一下程序,让它生成target文件。

image

然后再运行clean命令。在IDEA的右侧栏找到Maven Projects(如果没有则在菜单栏找到View—>第一行Tool Windows—>Maven Projects)。

image

双击clean命令。

这时,控制台打印输出:

image

这时,再看一下工作空间,target文件夹被删除了。

image

②、compile:编译项目,并将编译的文件放在target目录。

双击compile命令。这时,控制台打印输出:

image

再看一下工作空间,生成了 target文件夹。

image

点击 target文件夹, 不仅仅有 classes文件夹,里面放置 包名/HelloMaven.class ,还生成了其他的文件夹。

image

③、test:使用单元测试框架运行测试代码。

双击test命令。这时,控制台打印输出:

image

再看一下工作空间,target 除了刚才的那些文件夹之外,又添加了几个。 test-classes,,里面放置了 包名/HelloTest.class。

image

④、package:对项目进行打包,放在target目录中。

双击package命令。这时,控制台打印输出:

image

再看一下工作空间,target 除了刚才的那些文件夹之外,又多了一个 项目名-版本-快照.jar包。

image

⑤、install:将包安装至本地仓库,以让其它项目依赖。

双击install命令。这时,控制台打印输出:

image

再看一下工作空间,target 相对于package来说,没有任何改变。 改变的是本地仓库。根据红框的地址找到我们安装的jar包:D:\Maven\maven-repository\com\thr\hellomaven\1.0-SNAPSHOT。里面有 jar包和相应的 pom.xml 文件,只是pom.xmlde 名称变成了 jar包名.pom。

image


Maven提供了一些列指令来实现项目的编译、测试、安装和发布等功能。

在IDEA中,通过菜单 “View” > “Tool Windows” > “Maven” 打开Mave操作界面,可以看到这些指令。

image-20210228193934407

命令 描述
clean 清除项目编译后的文件
validate 验证工程是否正确、所有需要的资源是否可用。可以验证pom.xml文件的正确性
compile 编译项目
test 执行项目中的测试用例
package 将项目打包
verify 运行任何检查,验证包是否有效且达到质量标准
install 将项目打包进本地仓库
site 生成项目的网页形式的文档
deploy 将项目打包发布到远程仓库

上述命令也可以在命令行(shell或CMD)中执行

mvn clean			#清除编译结果
mvn compile 		#编译源代码		
mvn test-compile 	#编译测试代码	
mvn test			#运行测试		
mvn package			#打包		 
mvn install			#安装到本地仓库	

3.6 Maven插件介绍

我们知道,Maven生命周期是依靠各种插件来完成的,而我们打开Maven的源文件并没有发现有plugin,这是因为我们在第一次使用Maven的时候它会给我们自动下载,还记得在第一次配置并且运行Maven项目的时候,加载的时间有点长,输出界面也一直在下载东西,此时就在下载我们的插件。所以我们是可以找的下载的插件的,定位到:%本地仓库%\org\apache\maven\plugins,可以看到一些下载好的插件:

image

①、插件的目标(Plugin Goals)

一个插件通常可以完成多个任务,每一个任务就叫做插件的一个目标。如执行mvn compile命令时,此时的 compile 就是一个目标,调用的插件和执行的插件目标如下:

image

每个插件都有哪些个目标,官方文档有更详细的说明:Maven Plugins

②、插件如何与生命周期进行绑定?

插件与生命周期绑定是通过将插件的目标(goal)绑定到生命周期的具体阶段(phase)来完成的。如:将maven-compiler-plugin插件的compile目标绑定到default生命周期的compile阶段,完成项目的源代码编译:

img

③、内置的绑定

Maven对一些生命周期的阶段(phase)默认绑定了插件目标,因为不同的项目有jar、war、pom等不同的打包方式,因此对应的有不同的绑定关系,其中针对default生命周期的jar包打包方式的绑定关系如下:

img

第三列中【插件:目标】,其中冒号后面即是绑定的插件目标,冒号前面是插件的前缀(prefix),是配置和使用插件的一种简化方式。详细可查看Maven官方文档:Plugin Prefix

④、自定义绑定

用户可以根据需要将任何插件目标绑定到任何生命周期的阶段,如:将maven-source-plugin的jar-no-fork目标绑定到default生命周期的package阶段,这样,以后在执行mvn package命令打包项目时,在package阶段之后会执行源代码打包。

<build>
    <plugins>
        <plugin>
            <groupId>org.apache.maven.plugins</groupId>
            <artifactId>maven-source-plugin</artifactId>
            <version>2.2.1</version>
            <executions>
                <execution>
                    <id>attach-source</id>
                    <phase>package</phase><!-- 要绑定到的生命周期的阶段 -->
                    <goals>
                        <goal>jar-no-fork</goal><!-- 要绑定的插件的目标 -->
                    </goals>
                </execution>
            </executions>
        </plugin>
    </plugins>
    ……
</build>

<plugin>插件元素中,<execution>元素是执行目标,<phase>元素代表的是绑定的生命周期的阶段,<goal>元素代表要绑定的插件的目标。 插件是前面artifactId中定义好的,goals相当于该插件中的一个功能,该功能将在phase绑定的生命周期阶段执行。这种方式就属于自定义绑定,即在某个特定的生命周期阶段执行某个插件的功能,此时大多数时候是内置绑定的。

⑤、配置插件

Maven插件高度易扩展,可以方便的进行自定义配置。如:配置maven-compiler-plugin插件编译源代码的JDK版本为1.7:

<!-- 编译插件 --> 
<plugin>
    <groupId>org.apache.maven.plugins</groupId>
    <artifactId>maven-compiler-plugin</artifactId>
    <configuration>
        <source>1.7</source>
        <target>1.7</target>
        <encoding>UTF-8</encoding>
    </configuration>
</plugin>
  • source: 源代码编译版本;
  • target: 目标平台编译版本;
  • encoding: 字符集编码。

3.7 Maven项目配置文件(pom.xml)常见配置节

节点 含义
project pom文件顶级元素
modelVersion pom模型版本
groupId 项目组织的唯一表示,常见为公司名或域名倒写 org.apache
artifactId 项目唯一表示,对应项目名称
version artifactId的版本号,如1.0.0-SNAPSHOT,SNAPSHOT表示快照版,RELEASE表示发行版
name 项目的展现名称,在maven生成文档中使用
url 项目主页URL,在maven生成文档中使用
description 项目的表述,在maven生成文档中使用
packaging 项目打包方式,一般为jar或war
parent 项目的父依赖,类似Java继承,当前项目可以继承父依赖中配置的依赖和属性;需要指定父依赖的groupId、artifactId、version和relativePath
dependencies 定义此项目所依赖的关系集,在子节点dependency中添加具体的依赖
dependency dependencies的子节点,配置具体的依赖,需要指定具体依赖的groupId、artifactId、version,以及一些扩展配置如scope(compile/provided/runtime/test/system)optional(false / true)
properties 定义一些常量,可在pom文件的其他地方引用
build 构建选项,描述如何编译和打包项目,具体工作通过plugin完成:maven-clean-plugin、maven-resources-plugin、maven-compiler-plugin、maven-surefire-plugin、maven-war-plugin 或 maven-jar-plugin、maven-install-plugin、maven-deploy-plugin

4、maven的核心概念和依赖管理

4.1 Maven的坐标

我们知道,Maven的核心概念是依赖的管理,那么Maven是怎么来引入jar包的呢?答:通过坐标。

在Maven中是,坐标是Jar包的唯一标识,然后Maven通过坐标在仓库中找到项目所需的Jar包。

如下代码中,groupIdartifactIdversion构成了一个Jar包的坐标(简称gav)。

<dependency>
    <groupId>junit</groupId>
    <artifactId>junit</artifactId>
    <version>4.11</version>
    <scope>test</scope>
</dependency>

Maven坐标主要组成:

  • groupId:组织标识(包名)
  • artifactId:项目名称
  • version:项目的当前版本

4.2 Maven的仓库

Maven的仓库,就指的就是存放jar包的地方。 在Maven中的仓库分为三个类型,它们分别为:本地仓库、远程仓库和中央仓库。其实远程仓库它包含了中央仓库,私服,和其他公共库。

  1. 本地仓库:就是用来存储从远程仓库或中央仓库下载的插件和jar包,项目使用一些插件或jar包,优先从本地仓库查找。默认本地仓库位置在 ${user.dir}/.m2/repository${user.dir}表示windows用户目录。
  2. 远程仓库:就是当本地仓库没有相应的插件和jar包,maven会去远程仓库下载,默认回去中央仓库。远程仓库可以在互联网内也可以在局域网内。
  3. 中央仓库 :就是Maven团队自己维护的仓库,它服务于整个互联网,里面几乎存储了世界上大部分流行的开源项目构件,在maven软件中内置一个远程仓库地址。由于不在国内,所以我们从中央仓库下载jar包非常慢,所以国内推荐使用阿里巴巴维护的那个远程仓库。

image

Maven下载jar包的优先级:

  • ①、如果本地仓库有,就从本地仓库里拿。
  • ②、如果本地仓库没有,就从私服拿,顺便下载一份到本地仓库(如果有私服的话)。
  • ③、如果私服没有,判断是否配置了镜像,如果配置了镜像,就去镜像那儿拿,如果没有没有配置镜像,就从中央仓库那拿。
  • ④、如果中央仓库也没有,就抛出异常,坐标不对。

所以, Maven的各个仓库的优先级是:本地仓库 > 私服 > 远程仓库

4.3 依赖的管理

依赖指的是项目与jar包之间的相互依赖,比如我们在使用Spring框架的时候,需要用到Spring依赖的jar包。而依赖管理指的就是使用Maven来管理项目中使用到的jar包,Maven管理的方式就是“自动下载项目所需要的jar包,统一管理jar包之间的依赖关系”。比如在文件上传的时候,光光有common-fileupload这个jar包是不行的,common-fileupload还依赖于common-io这个包jar包,此时由于Maven的依赖管理机制,都会帮我们自动下载这些包,我们并不需要管。

image

我们一般添加依赖都会去Maven的仓库去查找,网站为:https://mvnrepository.com/

image

4.4 依赖的配置

依赖的配置就是我们在Maven的项目中的pom.xml中来配置我们的依赖。这一步大家都知道,但是对于Maven坐标中的其它属性可能并不认识,下面介绍一下:

<dependencies>
    <dependency>
        <groupId>junit</groupId>     
        <artifactId>junit</artifactId>     
        <version>4.11</version>
        <package>...</package>
        <type>...</type>
        <scope>...</scope>
        <optional>...</optional>
        <exclusions>     
            <exclusion>     
                <groupId>...</groupId>     
                <artifactId>...</artifactId>     
            </exclusion>
        </exclusions>     
    </dependency>        
</dependencies>

这些元素标签的详细介绍:

  1. dependencies:用来管理依赖的总标签,一个 pom.xml 文件中只能存在一个这样的标签。
  2. dependency:包含在dependencies标签中,可以有无数个,每一个表示一个依赖。
  3. groupId,artifactId和version:依赖的基本坐标,对于任何一个依赖来说,基本坐标是最重要的,Maven根据坐标才能找到需要的依赖。
  4. package:依赖的打包类型。普通项目为jar包,Web项目为war包。
  5. type:依赖的类型,对应于项目坐标定义的packaging。大部分情况下,该元素不必声明,其默认值是jar。
  6. scope:依赖的范围,默认值是 compile。后面会进行详解。
  7. optional:标记依赖是否可选。
  8. exclusions:用来排除传递性依赖,后面会进行详细介绍。

4.5 依赖的范围

依赖的范围:就是该依赖在各种环境下是否还可以使用。比如测试的jar包 junit4.11,,我们只希望在代码测试的时候使用,不希望在布署项目的时候把这个jar包放置上去,所以我们可以将Junit依赖设置为test范围的依赖。 还有server-api.jar, jsp-api.jar 是在代码编译的时候有用,但在布署项目的时候,是没有的用的,并且是不能把这个两个 jar包放置到tomcat里面的,因为tomcat里面有这两个jar包,会造成冲突, 所以一定要把这两个jar包给去掉,所以此时我们就要将它们设置为provided范围的依赖。这就是依赖的范围。

依赖范围有六种: compile、test、provided、runtime、import和system, 其中import和system不常用,所以就不介绍了。maven的依赖范围用 <scope>元素表示的。

  1. complie:编译依赖, 是默认的依赖范围。 在main 目录下的代码可以访问这个范围下的依赖,即jar包。 test 目录下的代码也可以访问这个范围下的依赖。 布署到 tomcat下时, 要把这个依赖放置在 WEB-INF 下的 lib 文件夹里面。
  2. test:测试依赖,仅仅是测试使用的。 在main目录下的代码不能访问这个依赖, test 目录下的代码可以访问这个依赖, 布署到tomcat下时, 不会把这个依赖放置在 WEB-INF下的 lib文件夹里面。 如 junit 4.11这个依赖。
  3. provided:提供依赖 在main目录下的代码可以访问这个依赖, test目录下的代码也可以访问这个依赖, 但在布署到tomcat下时,不会把这个依赖放置在 WEB-INF 下的lib文件夹里面。 如 servlet-api, jsp-api
  4. runtime:运行依赖。 main目录下的代码不能访问这个依赖, test目录下的代码可以访问这个依赖, 布署到tomcat下时,会把这个依赖放置在 WEB-INF 下的lib 文件夹里面。 如 jdbc 驱动

总结成一张表就可以知道依赖范围表示的作用域如下:

依赖范围 对于编译执行环境有效 对于测试执行环境有效 对于运行时执行环境有效 例子
compile spring-core
test junit
provided servlet-api
runtime jdbc

4.6 依赖的传递

依赖的传递:如果我们的项目引用了一个Jar包,而该Jar包又引用了其它Jar包,那么此时的项目与引入的其它jar包就是传递依赖,但是在默认情况下项目编译时,Maven会把直接引用和简洁引用的Jar包都下载到本地。

image

其中项目A直接依赖于B,而B也直接依赖于C,那么A就是间接依赖于C的,这就是传递性依赖。但是传递性依赖可能会产生依赖冲突。

如:项目A需要引入依赖包B,依赖包B又引入了依赖包C,那么B是A的直接依赖,C是A的传递依赖。如果项目A还需要引入依赖包D,依赖包D也引用了依赖包C,当依赖包B引用的C和依赖包D引用的C版本不同时,则发生了依赖冲突。

image

4.7 依赖的冲突

刚刚在上面说了,如果项目中引入了多个相同的jar,而jar包的版本不同就会产生依赖冲突。但是Maven才不会这么蠢,Maven中采用了两种避免冲突的策略:①、短路径优先;②、声明优先。因此在Maven中实际上是不存在依赖冲突的。

①、短路优先:就是哪个传递依赖离它最近则就优先选择它。

image

通过上面的图片我们可以分析出:

  • 项目A——>B——>C——>D
  • 项目A——>B——>D

第二条路径是离项目A最近的,也就是路径最短的。所以项目A最后用的是B依赖的D的jar包。

但是我们思考一下,如果传递依赖的路径相同那么它们会怎么选择呢?我们接着往下看。

②、声明优先:就是谁先声明的就先选择谁呗。

image

通过上面的图片我们可以分析出:

  • 项目A——>B——>C
  • 项目A——>D——>C

可以发现它们的路径是一样的,那此时就是按照谁先声明的就选择谁。在pom.xml 的依赖 <dependencies> </dependencies> 里面, 先放置哪一个,就用哪一个。 你先放置B, 那么C就是 B里面的, 你先放置D, 那么C就是D里面的。 所以在放置依赖时,有一定的顺序。

4.8 依赖的排除

依赖的排除:就是排除掉我们不想要的依赖。比如:项目A依赖于B,B依赖于C,但有可能C依赖是不兼容的,会对项目造成一定的影响。此时,我们可以使用关键字exclusion排除C依赖。我们以spring-aop依赖为例:spring-aop是依赖于spring-beans和spring-core的。

image

假如我们需要排除掉spring-beans:

<dependency>
  <groupId>org.springframework</groupId>
  <artifactId>spring-aop</artifactId>
  <version>5.2.6.RELEASE</version>
  <exclusions>
    <exclusion>
      <groupId>org.springframework</groupId>
      <artifactId>spring-beans</artifactId>
    </exclusion>
  </exclusions>
</dependency>

排除后的结果为:

image

5、maven的继承与聚合

5.1 Maven的继承

Maven的继承,就是子模块会自动继承父模块中定义的一些依赖、插件、属性等等。我们使用继承的目的是为了消除重复性,实际项目中最常用的是把子模块pom中很多相同的依赖配置提取出来,统一锁定在父模块的pom中。如:grouptId、artifactId、version等等。然后在使用的时候子模块会直接继承父模块的依赖版本号,子模块中不再需要指定具体版本号,方便统一管理项目的依赖问题。

Maven继承的关系:

image

继承使用到的元素是<parent>,对于继承关系的父模块pom来说,它不知道自己被哪些子模块继承了,而对于子模块的pom来说,它必须知道自己的父模块pom是谁。所以我们必须要在每个子模块的pom文件中添加指向父模块的引用,如下所示。

<parent>
    <artifactId>Parent</artifactId>
    <groupId>com.thr</groupId>
    <version>1.0-SNAPSHOT</version>
</parent>

还有要注意的是父模块坐标中的packaging必须是pom类型,否则子模块就不会继承。

<groupId>com.thr</groupId>
<artifactId>Parent</artifactId>
<packaging>pom</packaging>
<version>1.0-SNAPSHOT</version>

Maven继承的实际使用举例:

①、创建父工程——Parent

image

②、然后分别创建三个子模块,Child1、Child2和Child3。(IDEA右击项目选择Module)

image

③、项目创建后的目录为。

image

④、项目创建后父模块和子模块的pom。

1)父模块中的pom文件:

image

2)子模块中的pom文件(其它两个省略):

image

⑤、然后我们统一管理项目的依赖版本,在父模块中使用版本锁定和版本常量的方法来锁定版本(详细可参考:上章的版本管理部分),并且在相应的子模块中导入依赖。

1)在父模块pom中设置依赖管理:

<?xml version="1.0" encoding="UTF-8"?>
<project xmlns="http://maven.apache.org/POM/4.0.0"
         xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
         xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd">
    <modelVersion>4.0.0</modelVersion>

    <groupId>com.thr</groupId>
    <artifactId>Parent</artifactId>
    <packaging>pom</packaging>
    <version>1.0-SNAPSHOT</version>

    <!-- 集中定义依赖版本号 -->
    <properties>
        <spring.version>5.2.6.RELEASE</spring.version>
        <junit.version>4.11</junit.version>
    </properties>

    <!-- 版本锁定,当子模块中有需要并且自行添加了具体依赖后才有效,
    它仅仅是起到锁定作用,不下载依赖包 -->
    <dependencyManagement>
        <dependencies>
            <dependency>
                <groupId>junit</groupId>
                <artifactId>junit</artifactId>
                <version>${junit.version}</version>
                <scope>test</scope>
            </dependency>

            <!-- https://mvnrepository.com/artifact/org.springframework/spring-core -->
            <dependency>
                <groupId>org.springframework</groupId>
                <artifactId>spring-core</artifactId>
                <version>${spring.version}</version>
            </dependency>
        </dependencies>
    </dependencyManagement>

</project>

2)在子模块中的pom设置需要的依赖:

<?xml version="1.0" encoding="UTF-8"?>
<project xmlns="http://maven.apache.org/POM/4.0.0"
         xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
         xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd">
    <!--父模块的引用-->
    <parent>
        <artifactId>Parent</artifactId>
        <groupId>com.thr</groupId>
        <version>1.0-SNAPSHOT</version>
    </parent>
    <modelVersion>4.0.0</modelVersion>

    <artifactId>Child1</artifactId>

    <!--依赖包的下载仍然有dependencies管理-->
    <dependencies>
        <dependency>
            <groupId>junit</groupId>
            <artifactId>junit</artifactId>
            <!-- 版本号由父模块里面统一指定不再需要特别指定 -->
            <!--<version>4.11</version>-->
            <scope>test</scope>
        </dependency>
        <dependency>
            <groupId>org.springframework</groupId>
            <artifactId>spring-core</artifactId>
        </dependency>
    </dependencies>
</project>

补充:可继承的POM元素如下(红色为常用的元素)

  • groupId:项目组ID,项目坐标的核心元素。
  • version:项目版本,项目坐标的核心因素。
  • description:项目的描述信息。
  • organization:项目的组织信息。
  • inceptionYear:项目的创始年份。
  • url:项目的URL地址。
  • developers:项目的开发者信息。
  • contributors:项目的贡献者信息。
  • distributionManagement:项目的部署配置。
  • issueManagement:项目的缺陷跟踪系统信息。
  • ciManagement:项目的持续集成系统信息。
  • scm:项目的版本控制系统。
  • malilingLists:项目的邮件列表信息。
  • properties:自定义的Maven属性。
  • dependencies:项目的依赖配置。
  • dependencyManagement:项目的依赖管理配置。
  • repositories:项目的仓库配置。
  • build:包括项目的源码目录配置、输出目录配置、插件配置、插件管理配置等。
  • reporting:包括项目的报告输出目录配置、报告插件配置等。

5.2 Maven的聚合

Maven的聚合,就是用多个子模块聚合成一个整体模块,它们是整体与部分的关系,通常在定义一个整体后,再去分析这个整体的组成结构。例如一辆汽车是由轮胎、发动机、底盘、电器设备等等聚合而成。

Maven聚合的关系:

image

聚合使用到的元素是。对于聚合模块来说,它知道有哪些被聚合的模块,而对于被聚合的模块来说,它们不知道被谁聚合了,也不知道它的存在。所以我们要在聚合模块中添加指向被聚合模块的引用,如下。

<modules>
    <module>../被聚合模块1</module>
    <module>../被聚合模块2</module>
    <module>../被聚合模块3</module>
</modules>

注意:module中的路径为相对路径。

例如前面继承例子中的Child1、Child2和Child3这三个模块,我们对它进行聚合。

<!--在父模块中聚合-->
<modules>
    <module>Child1</module>
    <module>Child2</module>
    <module>Child3</module>
</modules>

image

聚合完成之后我们在使用Maven命令执行项目时,整个项目都会被构建,例如我们执行mvn compile指令。运行后如下图。

image

注意:这里被聚合模块的执行顺序不是按照元素中声明的先后顺序执行的,而是Maven在编译时会根据pom.xml中配置的modules得出一个反应堆构建顺序,并按照这个顺序编译项目模块。所以建议我们在创建项目的时候为项目模块提供一个合理的Name,因为构建的结果中是通过各个模块中配置的Name来标识每一个项目模块的构件状态的

反应堆

对于单模块Maven项目而言,反应堆就是整个项目本身。而对于多模块的Maven项目,反应堆是整个项目所有模块组成的一个构建结构,包含模块之间继承与依赖的关系。模块间的依赖关系会将反应堆构成一个有向非循环图。

裁剪反应堆

一般来说,我们要么构建整个项目,要么构建单个模块,但是有些时候,我们会想要仅仅构建这个完整的反应堆中的某些模块,所以我们需要裁剪反应堆。

Maven提供的如下几条裁剪反应堆命令:

  • -pl –projects:构建指定的模块,多个模块用,分隔,不会构建所列模块的依赖
  • -am alse mak:``构建模块同时构建所列模块依赖的其他模块
  • -amd alse make dependency:构建模块同时构建依赖当前模块的其他模块
  • -rf resume –from:在计算出的反应堆顺序基础上,从指定模块开始向后构建

命令的详细使用可以参考这篇博客:Maven 反应堆、按需构建多模块,玩转Maven反应堆(反应堆的构建顺序,裁剪反应堆)

在实际的开发中,我们通常会将聚合和继承合二为一,也就是合在一起使用。但是聚合和继承是两个不同的概念,它们二者之间是没有什么关系的。

6、IDEA构建Maven多模块Web项目

在前面的章节中我们介绍了Maven的继承和聚合,所以这一章我们实战一下,使用Maven来创建一个Web的多模块项目。我们创建的多模块为项目结构如下:

img

6.1 创建父模块

①、首先File——>New——>Project,创建一个父模块system-parent。

image

②、输入groupid和artifactid,然后next。

image

③、最后finish

image

④、因为父模块一般是用来管理项目的依赖的,所以src目录是没有用的,我们把它删除。

image

这样父模块就创建好了,接下来我们创建子模块。

6.2 创建子模块

(1)、创建普通子模块system-core

①、右击父模块,选择Module。

image

②、普通Java项目不要勾选

image

③、输入项目名称,并且选择是否继承与聚合(默认就好,不管)

image

④、最后Finish

image

⑤、这样system-core就创建完成了

image

同时我们注意此时父模块和子模块中pom的变化。

image

(2)创建web子模块system-web。有两种方式

方式一:创建maven项目时选择maven-archetype-webapp

①、勾选Create from archetype,并且选择maven-archetype-webapp。

image

②、输入项目名字

image

③、选择Maven路径

image

④、最后选择Finish

image

⑤、然后就创建好了

image

但是这种方法创建的项目是没有java和resources文件的,需要我们自己添加。

⑥、选择【File—>Project Structure或者按快捷键Ctrl+Alt+Shift+S】打开如下界面。

image

⑦、我们分别创建java和resources文件,并且给它们设置相应的类型,右击main目录创建。

GIF 2020-6-26 22-07-52

然后项目就有这两个目录了,至此,一个web的模块就创建完成了。

方式二:普通Java项目插入Web板块。

①、首先我们创建一个system-web1的普通Java项目(由于这里不想删掉system-web,所以在后面加了个数字),和前面创建system-core的方法一样。

image

可以发现是没有webapp目录的,下面我们插入Web模块。

②、插入Web模块。选择【File—>Project Structure或者按快捷键Ctrl+Alt+Shift+S】打开如下界面。

image

③、选择你刚刚创建的模块,然后点击上面的加号。

image

③、点击加号后选择Web。

image

④、然后修改一下webapp的路径

注意路径是当前模块下的 src\main\wabapp。

image

⑤、修改web.xml的路径

路径同样是当前模块下的 src\main\wabapp。

image

⑥、这样就创建完成了,和方法一的效果是一样的。

image

这两种方式创建的都是一个web模块。

6.3 构建与运行

①、首先在system-core模块中添加一个Hello类,

image

②、在system-web的pom.xml文件中导入system-core依赖,如下:

image

③、在system-web中添加index.jsp页面,在该页面中调用system-core模块中的方法,内容如下:

image

④、然后配置tomcat运行,点击IDEA上方的Edit Configuration。

image

⑤、点击+号,然后选中本地tomcat

image

image

⑥、配置tomcat的名称和路径

image

⑦、在Deployment选项卡中点击+号选择artifact

image

选中创建的web模块

image

⑦、项目运行

image

或者在IDEA的下方找到Applicable Servers

image

⑧、运行效果

image

到此为止,在IDEA中使用Maven创建多模块Web项目也就完成了。

附:使用Nexus3搭建Maven私服

1 私服的介绍

私服指的就是私有服务器,是架设在局域网的一种特殊的远程仓库,但搭建私服的服务器可以访问外网,目的是代理远程仓库及部署第三方构建。有了私服之后,当开发人员需要使用Maven下载构件时,本地仓库会直接请求私服,私服上存在则下载到本地仓库,否则私服请求外部的远程仓库,将构件下载到私服,再提供给本地仓库下载,当然本地仓库也可以上传架构到私服供其他开发人员下载使用。

image

现在市面上有3种专门的maven仓库管理软件可以用来帮助我们搭建私服,分别是:

  1. Apache基金会的archiva:http://archiva.apache.org/
  2. JFrog的Artifactory:https://www.jfrogchina.com/
  3. Sonatype的Nexus:https://www.sonatype.com/

这些都是开源的私服软件,有免费的版本,也有收费的版本。而用的最多的是第三种Nexus,所以本文我们主要以这个来讲解,其他2种有兴趣的朋友可以去研究一下。

2 nexus介绍

Nexus是一个强大的Maven仓库管理器,它极大地简化了本地内部仓库的维护和外部仓库的访问。

如果使用了公共的Maven仓库服务器,可以从Maven中央仓库下载所需要的构件(Artifact),但这通常不是一个好的做法。

正常做法是在本地架设一个Maven仓库服务器,即利用Nexus私服可以只在一个地方就能够完全控制访问和部署在你所维护仓库中的每个Artifact。

Nexus在代理远程仓库的同时维护本地仓库,以降低中央仓库的负荷,节省外网带宽和时间,Nexus私服就可以满足这样的需要。

Nexus是一套“开箱即用”的系统不需要数据库,它使用文件系统加Lucene来组织数据。

Nexus使用ExtJS来开发界面,利用Restlet来提供完整的REST APIs,通过m2eclipse与Eclipse集成使用。

Nexus支持WebDAV与LDAP安全身份认证。

Nexus还提供了强大的仓库管理功能,构件搜索功能,它基于REST,友好的UI是一个extjs的REST客户端,它占用较少的内存,基于简单文件系统而非数据库。

3 为什么使用nexus

我们平时自己在开发的时候,都是通过maven的中央仓库或者是第三方远程仓库下载的jar,对于一个人来说要求不多。但如果是公司合作开发一个项目,而这个项目可能需要几十甚至上百人,那么整个团队中的每个人都从远程仓库中把需要依赖的jar下载到本地仓库,这不仅对公司的宽带来说要求比较高,而且重复的从maven仓库下载jar无疑加大了仓库的负载和浪费了外网带宽,如果网速慢的话,还会影响项目的进程。并且大部分公司为了保护数据安全,都会限制访问外网,所以项目组大部分人员是不能访问maven的中央存储库和其它远程仓库,那么开发人员又要从仓库下载jar包怎么办呢?此时公司一般都会搭建只限内网能够访问maven私服,然后把maven私服串联到一台有外网权限的机器,这样既节省了网络带宽也会加速项目搭建的进程,而且私服照样可以联通中央仓库和其它仓库。

img

4 nexus的优点

所以通过上面的分析总结出使用私服的好处有:

  • 节省外网带宽。
  • 加速Maven构建。
  • 部署第三方构件。
  • 提高稳定性,增强控制。
  • 降低中央仓库的负荷。
  • 控制和审计
  • 建立本地内部公用仓库

5 nexus的下载

前提:nexus是基于Java开发的,所以安装系统一定要配置好JDK。

官方网站:https://www.sonatype.com/

下载的网站:https://www.sonatype.com/nexus-repository-oss

好像现在国内已经访问不了这个网站了,反正我是FQ出去在官网下载的。

如果你翻不了墙,我这里也提供了百度网盘的链接:

链接:https://pan.baidu.com/s/1e66PEnIxROPjk3KZcur1sA 提取码:av8h

①、下载网站打开之后如下图。

image

②、然后填写邮箱(随便填写一下即可)。

image

③、下载你要哪个操作系统的NEXUS。

image

之后等待系统响应会弹出下载页面(网不好可能等的久一点)。下载之后的到一个压缩包。下面我们安装nexus。

6 win系统中安装nexus

①、首先我们解压下载的nexus压缩包,解压之后会产生两个文件目录nexus-3.24.0-02nexus-3.19.1-01和sonatyp-work。

image

②、启动nexus。在解压的nexus文件的bin目录下输入cmd。

GIF 2020-6-28 22-26-22

③、然后再输入nexus.exe /run运行。

GIF 2020-6-28 22-28-36

等待系统运行完成后,我们在浏览器访问:

http://localhost:8081/

注意:如果nexus在启动时出现了下面的异常请忽略掉它,这是编码问题 不影响使用。

java.io.UnsupportedEncodingException: Encoding GBK is not supported yet (feel free to submit a patch)

浏览器输入地址访问后页面是这样的则表示nexus成功启动了。(如果端口冲突,它的默认端口配置在etc/nexus-default.properties文件里自行修改)

image

因为nexus是使用java开发的web项目,并且内置了jetty web容器,所以可以直接在浏览器中运行。

7 nexus的登录

上面全都完成之后,我们还要登录才能使用nexus,点击上图右上角的Sign in,输入用户名和密码。

nexus默认用户名是admin,但是密码已经不是admin123了。网上大部分是以前的版本了,默认的登录账号为admin;登录密码为admin123。但是新版本已经不是了。

image604e41c7587418e913beaa0b8a17107d[4]

nexus新版本的密码是第一次启动的时候生成的,密码位于下面的文件中,我们有软件打开便可获取。

安装目录/sonatype-work/nexus3/admin.password

image

①、登录成功后会弹出一些设置,如下:

image

点击Next,设置新的登录密码(新密码要保存好),如下:

image

②、设置是否匿名访问,这个最好允许,否则访问很麻烦。

image

③、然后点击Next->Finish完成设置。

image

这样nexus的登录就完成了。如果要停止nexus的话,在启动的cmd窗口中按:Ctrl+C即可停止。

8 nexus的仓库类型

我们在登录nexus之后,点击【工具——>Repositories】。

image

可以发现Nexus仓库类型分为以下3个:

  • proxy(代理仓库):用来代理远程的公共仓库,默认是从远程中央仓库中寻找数据的仓库。它负责代理包
  • hosted(宿主仓库):用来部署我们自己项目打包的构建,供内部人员下载。它负责上传包
  • group(仓库组):用来合并多个hosted/proxy仓库,都加入到“maven-public”仓库组中,下载时按配置顺序从中依次查找。它负责提供包

①、proxy仓库

代理仓库是用来代理第三方公共的远程仓库,默认是从远程中央仓库中寻找数据的仓库,我们也可以通过代理仓库代理其它的maven仓库,如阿里的maven仓库等。当用户本地仓库没有构建时,就会在私服中查找,如果私服还没有,则通过被代理的仓库中下载构建,然后下载缓存在私服中供大家使用,这样的优势只要其中一个人从远程库下来了,以后大家都是从Nexus私服上进行下来,私服一般部署在内网,这样可以大大节约的宽带。

由于国内基本上都用的是阿里云的仓库,所以接下来我们在nexus中创建一个阿里云的maven代理仓库,来看下过程如下:

1)、在Repositories列表中点击【Create repository】,如下图:

image

2)、进入添加页面,我们要选择的是【maven2(proxy)】,它表示的是maven代理仓库,如下图:

image

3)、然后填写仓库名称、仓库类型、仓库代理地址,如下:

image

4)、最后点击底部的【Create repository】创建完成,如下图:

image

②、hosted仓库

宿主仓库用来部署我们自己项目打包的构建,主要是给我们的内部人员下载使用。我们可以将自己开发好的构建发布到宿主仓库中供其他开发人员使用。

nexus默认义了2个宿主仓库,分别是maven-releases, maven-snapshots。

  1. maven-releases:这里存放我们自己项目中发布的构建, 通常是Release版本,即发布的版本。
  2. maven-snapshots:这个仓库非常的有用, 它的目的是让我们可以发布那些Snapshots版本, 即不稳定,还需要测试的版本。

hosted仓库的创建和proxy仓库是一致的,具体步骤和上面基本一致。如下:

image

image

在创建的时候要注意Deployment Pollcy要改成“Allow redeploy”。

image

然后点击底部的【Create repository】创建完成。

③、group仓库

仓库组主要是将proxy仓库和hosted仓库合并,它可以合并多个proxy仓库和hosted仓库,所以当maven用户访问访问一个仓库组的时候,就可以间接的访问这个组内所有的仓库,而仓库组中多个仓库是有顺序的,当maven用户从仓库组下载构件时,仓库组会按顺序依次在组内的仓库中查找组件,查找到了立即返回给本地仓库,所以一般情况我们会将速度快的放在前面。仓库组内部实际上是没有构件内容的,他只是起到一个请求转发的作用,将maven用户下载构件的请求转发给组内的其他仓库处理。

下面我们将之前创建的maven-aliyun代理仓库和maven-test宿主仓库进入到仓库组,如下:

1)、首先打开maven-public,如下:

image

2)、把名称为maven-aliyun和maven-test的拖过去或者选中然后点击 > 按钮,同时也可以发现右边的成员已经默认添加了三个,分别是宿主仓库的两个(maven-releases、maven-snapshots)和代理仓库(maven-central)。

image

3)、由于阿里云的仓库在国内下载速度很快,所以我们把它放在中央仓库的前面。

image

最后点击Save保存即可。

9 配置maven从nexus下载构建

配置maven从nexus下载构建有两种方式:①、pom.xml方式。②、镜像方式。

①、pom.xml方式

1)、首先我们创建一个maven项目,并且修改该项目的pom.xml文件,加入如下内容:

<repositories>
    <repository>
        <id>maven-nexus</id>
        <url>http://localhost:8081/repository/maven-public/</url>
        <releases>
            <enabled>true</enabled>
        </releases>
        <snapshots>
            <enabled>true</enabled>
        </snapshots>
    </repository>
</repositories>

注意:url地址对应到nexus上的哪个仓库组,因为只有仓库组提供包,我们可以在nexus上面复制地址,如下:

image

2)、因为nexus是需要用户名和密码才能访问,所以在maven的setting.xml中添加如下配置(大概在125行左右),我们最好先备份一份原始的setting.xml文件。

<server>
  <id>maven-nexus</id>
  <username>admin</username>
  <password>123456</password>
</server>

注意:上面元素的值和pom.xml中的值必须一致。 元素中的username和password根据自己去设置,我这里密码设置的是123456。

3)、例如我们要下载jdbc的mysql连接驱动的jar包,首先确保本地仓库是没有的,否则会从本地仓库拿,如果有先删除。

<!-- https://mvnrepository.com/artifact/mysql/mysql-connector-java -->
 <dependency>
     <groupId>mysql</groupId>
     <artifactId>mysql-connector-java</artifactId>
     <version>8.0.16</version>
 </dependency>

image

4)、然后我们编译项目:mvn compile ,执行结果如下:

image

从运行结果可以发现mysql驱动的jar包从maven-nexus中下载了,下载地址正是我们nexus私服中的那个地址。

②、镜像方式

以上面创建的那个maven项目为例。

1)、修改maven的setting.xml文件,加入如下配置(大概在163行):

<mirror>
    <id>mirror-nexus</id>
    <name>nexus-mirror</name>
    <url>http://localhost:8081/repository/maven-public/</url>
    <mirrorOf>*</mirrorOf>
</mirror>

注意:上面mirrorOF配置的*,说明所有远程仓库都通过该镜像下载构件。

2)、登录的用户名和密码配置不变(id改了一下):

<server>
  <id>mirror-nexus</id>
  <username>admin</username>
  <password>123456</password>
</server>

id元素与上面setting.xml中配置的id同样必须相同。

3)、下载jdbc的mysql连接驱动的jar包,记得删除本地仓库的jar包。

image

4)、编译项目:mvn compile ,执行结果如下:

image

可以发现同样是从mirror-nexus中下载的jar。

10 配置本地构建上传至nexus

nexus配置部署有两种方式:①、maven上传。②、手动上传。

①、maven上传

我们知道,nexus私服的宿主仓库是用来存储用户自己上传的jar,它提供了两个默认的宿主仓库分别用来存放SNAPSHOT版本和RELEASE版本。

而我们在上传jar的时候只需要更改pom中的元素中内容即可:

  • 上传为 maven-snapshot 时 在1.0-SNAPSHOT加上-SNAPSHOT, 表示不稳定的,会反复发布、测试、修改的版本。
  • 上传为 maven-releases 时 要把1.0 中的-SNAPSHOT去掉,表示这是一个发布版本。

maven上传jar的具体操作如下:

1)、修改pom.xml文件,加入下面内容:

<distributionManagement>
    <repository>
        <id>release-nexus</id>
        <url>http://localhost:8081/repository/maven-releases/</url>
        <name>nexus-release</name>
    </repository>
    <snapshotRepository>
        <id>snapshot-nexus</id>
        <url>http://localhost:8081/repository/maven-snapshots/</url>
        <name>nexus-snapshot</name>
    </snapshotRepository>
</distributionManagement>

上面2个url分别对应的是nexus中两个宿主仓库的地址。

2)、修改settings.xml,配置nexus登录用户名和密码信息。

<server>
    <id>release-nexus</id>
    <username>admin</username>
    <password>123456</password>
</server>
 
<server>
    <id>snapshot-nexus</id>
    <username>admin</username>
    <password>123456</password>
</server>

id要与distributionManagement中id对应。

3)、执行 mvn deploy 命令,结果如下:

image

从运行结果可以发现我们的jar已经上传至maven-snapshot中了。

4)、查看上传的jar,我们访问nexus私服中快照版本仓库的地址:

http://localhost:8081/repository/maven-snapshots/

如果出现了如下页面,点击上面的browse链接。

image

然后我们就可以看到上传的jar包了。

image

如果别人要使用我的jar包的话,只需选中以pom结尾的文件,右边会显示这个jar的坐标。

image

至此maven上传jar包已经全部介绍完毕了。

release稳定版本发布到nexus私服和这个一样,就是改一下version元素后面的内容即可,所以就不演示了。

②、手动上传

手动上传一般是用来上传第三方给我们的jar包,例如某个合作商给了一个jar包,这时我们不能使用maven方式上传,而这个包远程仓库是不存在的,大家又要共同使用这个包,此时我们就可以手动将这个jar上传到私服供所有开发使用。但目前手动上传只支持发布稳定版本的构件。

1)、登录nexus之后,按照下图的步骤依次进行操作。

image

2)、我们把target目录下打包的项目的jar上传,并且依次填写好坐标信息,最后点击upload按钮。

image

3)、查看上传的jar,点击右边的Browse,然后选择maven-releases。

image

进来之后就可以看到我们手动上传的包了。

image

11 linux系统中安装nexus

当然我们一般都不会把nexus私服搭建在Windows系统中,而是建在Linux系统中,所以下面介绍在Linux系统中如何搭建私服。Linux版的nexus文件可以在官网下载,也可以在前面提供的百度网盘中获取。然后用Xftp工具上传到Linux系统中。

注意:nexus是基于Java开发的,所以安装系统一定要配置好JDK。可以参考:在CentOS7上配置JDK和Tomcat

①、上传nexus

首先在/opt 目录下新建一个nexus目录:

[root@localhost ~]# mkdir /opt/nexus

然后将nexus压缩包用Xftp上传到这个目录。

image

②、解压nexus

进入创建的nexus目录进行解压:

[root@localhost ~]# cd /opt/nexus/``[root@localhost nexus]# tar -zxvf nexus-3.24.0-02-unix.tar.gz``[root@localhost nexus]# ls``nexus-3.24.0-02 nexus-3.24.0-02-unix.tar.gz sonatype-work

③、配置虚拟机内存

nexus运行依赖于jvm,而我的nexus默认运行内存如下:

[root@localhost bin]# vi /opt/nexus/nexus-3.24.0-02/bin/nexus.vmoptions

image

它这个运行内存已经远大于系统物理内存,因为jvm分配的内存太大,会导致nexus启动不了,在运行的时候就会报错,报错信息如下:

image

上面就是说虚拟机运行环境的内存分配不够,所以我们要给它调整一下(测试环境下)。

进来之后按 i 键,改完后按esc然后 :wq 完成。

image

④、启动nexus

nexus常用的一些命令包括:./nexus {start|stop|run|run-redirect|status|restart|force-reload}。

start和run启动nexus的区别:start不能看到nexus的运行信息,而run可以,甚至打印错误信息。

下面我们启动nexus(默认端口是8081):

image

说明已经启动成功,上面warning意思是nexus建议不要用root用户来启动nexus,但并不影响启动(nexus的启动较慢,等个1-3分钟)。

④、开放8081端口

#开放端口``firewall-cmd --zone=public --add-port=8081/tcp --permanent``#重启端口``firewall-cmd --reload``#查看开放端口``firewall-cmd --zone=public --list -ports

⑤、验证效果

浏览器输入 http://ip:8081/ 之后如果有nexus界面则表示成功了。

image

⑥、登录nexus

登录账号为:admin,密码在/opt/sonatype-work/nexus3/admin.password

[root@localhost bin]# vi /opt/nexus/sonatype-work/nexus3/admin.password

image

参考资料:

  1. https://cloud.tencent.com/developer/article/1538941
  2. https://www.cnblogs.com/kevingrace/p/6201984.html
posted @ 2022-09-04 14:45  Angelzheng  阅读(116)  评论(0编辑  收藏  举报