Maven知识记录

一)初识Maven私服

私服即私有的仓库。maven把存放文件的地方叫做仓库,我们可以理解成我门家中的储物间。而maven把存放文件的具体位置叫做坐标。我们项目中pom.xml文件里引入的jar文件就存放在了maven仓库中。

maven的仓库分两种:

1.本地仓库

我们个人电脑中安装maven时分配的仓库。用于存放我们所有项目中所需的资源文件(多为jar文件)。需要说明的是初次安装maven时我们的本地仓库是没有任何文件的,只有我们在对应的项目里运行maven命令时才会在本地仓库生成文件。如果本地仓库没有,会首先尝试从远程仓库下载构件至本地仓库,然后再使用本地仓库的构件。
默认的仓库地址${user.home}/.m2/repository通过手动更改配置文件即可改变本地仓库存放位置。配置文件settings.xml存放在 安装maven路径\conf下(例如:D:\apache-maven-3.0.5\conf\settings.xml) 搜索localRepository即可修改。

2.远程仓库

简单的理解为通过网络访问的仓库被称为maven的远程仓库。综合来讲可分为三类:

中央仓库 中央仓库是由 Maven 社区提供的仓库,其中包含了大量常用的库。该仓库由maven官方来维护,本地默认安装的maven无需配置。官方提供浏览器访问地址: https://search.maven.org/#browse项目中配置的仓库地址: https://repo1.maven.org/maven2/

三方仓库: 可以理解为民间组织非官方的仓库。较为常用的当属国内的阿里云仓库。之所以有这些第三方仓库的存在。是为了弥补官方仓库的一些不足。例如:项目所需jar文件在官方仓库找不到、国内访问官方仓库的网络速度过慢等等原因。

私有仓库:前面说了这么多终于绕到了今天的主题—私服。其实我们所说的私服就是远程仓库其中的一种。准确的说是只给自己公司使用的maven仓库。比起上面两种类型的仓库,私服除了可以节省网络带宽以外,更多的是提供公司内部使用的jar包。例如:公司通过业务积累封装出一套很有价值的基础项目,公司希望这个基础项目只被公司内被使用。这时我们就可以将此基础服务项目打成jar包上传到我们的私有仓库里。其他的项目就可以通过maven引入jar包的方式去使用。因此公司搭建自己的maven私服是很有必要的。

常用远程仓库:

搭建Maven私服的软件有哪些

  1. Archiva

官网地址: http://archiva.apache.org/简介:Apache Archiva™是可扩展的存储库管理软件,可帮助您维护自己的个人或企业范围 内的构建工件存储库。它是Maven, Continuum和ANT等构建工具的完美伴侣。Archiva提 供了多种功能,其中包括远程存储库代理,安全访问管理,构建工件存储,交付,浏览,索 引和使用情况报告,可扩展的扫描功能……等等!

  1. Artifactory

官网地址: https://www.jfrogchina.com/artifactory简介:管理制品而不是源代码持续、自动地更新信息已经成为一切成功运维的关键因素.JFrog 通过持续更新的实践彻底改变了软件世界, 其速度和连续性永远改变了组织管理和发布软件的 方式.

  1. Nexus

官网地址: https://www.sonatype.com/download-oss-sonatype简介:正如官网的描述那这样 The world’s first and only universal artifact repository that’s FREE to use.(世界上第一个也是唯一的免费使用的通用工件存储库。)也正因为如此nexus是目前市面上使用最多的maven私服搭建软件。
因此,这里使用nexus来做搭建私服的演示。上面的官网地址下载软件较慢,我这里提供了网盘下载地址如下:
网盘下载地址: https://pan.baidu.com/s/1saLf5Z0FwWRkjHY6eSzZLg 提取码:qz5z

二)使用Nexus搭建Maven私服

Linux环境下安装Nexus

有一点需要说明的是搭建nexus时尽量不要使用root用户直接安装运行,官方应该是处于安全考虑给出的建议,所以我这里创建了nexus用户作为日后维护私服帐号。

1.使用root创建nexus用户

我这里密码设置的是123456,因此提示过于简单。实际使用环境中这个密码要设置的复杂些。

1
2
3
4
5
6
7
8
9
[root@linux ~]# useradd nexus
[root@linux ~]# passwd nexus
更改用户 nexus 的密码 。
新的 密码:
无效的密码: 过于简单化/系统化
无效的密码: 过于简单
重新输入新的 密码:
passwd: 所有的身份验证令牌已经成功更新。
[root@linux ~]#

2. 验证用户是否创建成功、密码是否设置成功

用户创建成功、密码设置成功后。下面切换到nexus用户。我这里为了验证nexus的密码所以预先切换到了另外一个普通用户

1
2
3
4
5
6
[root@linux ~]# su wangwu
[wangwu@linux root]$
[wangwu@linux root]$
[wangwu@linux root]$ su nexus
密码:
[nexus@linux root]$

如上出现nexus@linux 表示创建的nexus用户成功并且设置密码生效。

3. 上传nexus安装包

使用cd ~切换到nexus用户的家目录。打开FTP上传文件工具把nexus上传到服务器。

1
2
3
4
[nexus@linux ~]$ ll
总用量 132256
-rw-r--r--. 1 root root 135426386 7月 20 00:27 nexus-3.19.1-01-unix.tar.gz
[nexus@linux ~]$

4. 解压nexus安装包

1
2
3
[nexus@linux ~]$ tar -zxvf nexus-3.19.1-01-unix.tar.gz
[nexus@linux ~]$ ls
nexus-3.19.1-01 nexus-3.19.1-01-unix.tar.gz sonatype-work

5. 启动nexus服务

1
2
3
4
5
6
7
8
9
10
[nexus@linux ~]$ cd nexus-3.19.1-01/bin/
[nexus@linux bin]$ sh nexus start
Starting nexus
[nexus@linux bin]$ sh nexus status
nexus is running

# 说明一下nexus命令
# 启动: sh nexus start (后台运行) sh nexus run(输出信息运行)
# 停止:sh nexus-3.19.1-01/bin/nexus stop
# 状态:sh nexus-3.19.1-01/bin/nexus status

6. 验证nexus安装是否成功

浏览器中输入ip:8081,出现如下画面,说明安装成功。 这里需要到提示的路径中获取nexus默认登录密码

1
2
3
4
5
[nexus@linux bin]$ cat /home/nexus/sonatype-work/nexus3/admin.password
ba7fe33c-cd30-4a2b-aba6-d399f8ed34e3[nexus@linux bin]$
[nexus@linux bin]$
#ba7fe33c-cd30-4a2b-aba6-d399f8ed34e3 为我的初始登录密码,
#输入此密码登录成功后按步骤需要重新设置一个新的密码,按步骤操作即可,这里不做演示了。

7. 设置nexus开机启动

实际环境中需要设置下开机nexus自启动,这里因为nexus权限的原因需要切换回root用户下进行操作。

1
2
3
4
5
6
7
[nexus@linux bin]$ su root
密码:
[root@linux bin]#
[root@linux bin]# ln -s /home/nexus/nexus-3.19.1-01/bin/nexus /etc/init.d/nexus3
[root@linux bin]# chkconfig --add nexus3
[root@linux bin]# chkconfig nexus3 on
[root@linux bin]#

三)项目中使用maven私服

访问服务器地址验证成功,在我们项目里开始使用私服之前先了解一下maven依赖顺序,也就是mavne下载文件访问仓库的顺序。
1.本地仓库查找,找得到引入到项目,找不到执行下一步。
2.未设置远程仓库时,进行中央仓库搜索(maven官方提供的一号仓库)找得到下载到本地仓库后引入到项目,找不到给出错误信息。
3.若设置了远程仓库则按配置远程仓库地址的顺序下载到本地后引入到项目,同样找不到给出错误信息。
上面第三条提到按配置远程仓库地址的顺序进行搜索下载。下面简要说明下:

  • settings_mirror 的优先级高于central
  • settings_profile_repo 优先级高于 settings_mirror
  • settings_profile_repo 优先级高于 pom_repositories
  • settings_profile_repo 优先级高于 pom_profile_repo
  • pom_profile_repo 优先级高于 pom_repositories
  • pom_repositories 优先级高于 settings_mirror

最后搜素顺序如下:
local_repo > settings_profile_repo > pom_profile_repo > pom_repositories > settings_mirror > central

一、maven私服配置信息

地址: http://ip:8081(搭建maven私服的地址)
管理帐号:admin 管理密码:123456 (登录私服的账号、密码)
发包帐号:maven 发包密码:123456 (为了安全起见,使用管理账号单独创建的账号密码用于发包使用)

二、maven私服使用

普通项目成员即不需要向私服发布包的,只需要在 pom 文件中加入以下配置即可

1
2
3
4
5
6
7
8
9
10
11
12
13
<repositories>   
<repository>
<id>maven-public</id>
<name>maven-public</name>
<url>http://ip:8081/repository/maven-public/</url>
<releases>
<enabled>true</enabled>
</releases>
<snapshots>
<enabled>true</enabled>
</snapshots>
</repository>
</repositories>

配置说明:
其中 id 要和你的仓库名称一致,url 就是私服的仓库地址,就是type 为 group 的那个,它组合了一个 proxy 类型的和两个 hosted 类型的仓库。设置 snapshots 的 enabled 为ture,表示允许下载 snapshots 版本的包。

三、发布公共资源包到maven私服:

向私服仓库中发布包,首先需要对仓库有权限才可以,没有权限的用户是没办法发布的。
打开 maven 的配置文件 setting.xml ,找到 servers 节点在其中添加 server 节点,用户名和密码也可以是管理员创建的账号,但是需要对仓库有添加权限。
配置本地maven settings.xml 提示:两种配置方法
1.直接配置maven目录下的conf下的settings.xml文件。
复制该文件到用户目录下的.m2目录,两种方法配置效果是一样的,看个人喜好了,加载顺序是.m2下的settings.xml目录接着是maven config目录下的settings.xml。

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
<servers>    
<server>
<id>releases</id>
<username>maven</username>
<password>123456</password>
</server>
<server>
<id>snapshots</id>
<username>maven</username>
<password>123456</password>
</server>
</servers>
<mirrors>
<mirror>
<id>nexus</id>
<name>internal nexus repository</name>
<!--镜像采用配置好的组的地址-->
<url>http://ip:8081/repository/maven-public/</url>
<mirrorOf>!internal.repo,*</mirrorOf>
</mirror>
</mirrors>

配置需要上传到私服上的项目pom.xml配置信息

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
<distributionManagement>
<!--配置线上releases仓库地址,只要是正式版本都会上传到该地址
(注意要和settings.xml文件里面的配置名称相同)-->
<repository>
<id>releases</id>
<name>Releases</name>
<url>http://ip:8081/repository/maven-releases/</url>
</repository>
<!--配置线上snapshots仓库地址,只要是快照版本都会上传到该地址
(注意要和settings.xml文件里面的配置名称相同)-->
<snapshotRepository>
<id>snapshots</id>
<name>Snapshot</name>
<url>http://ip:8081//repository/maven-snapshots/</url>
</snapshotRepository>
</distributionManagement>

特别说明:当pom.xml中同时配置了releases仓库和snapshots仓库时。
pom.xml文件开头的版本配置1.0.0-SNAPSHOT为build到snapshots库,
pom.xml文件开头的版本配置1.0.0 (不带-SNAPSHOT) 的会build到releases库,
如果只配置了releases库而版本号写的是带-SNAPSHOT的,build到最后一步会报400错误,因为它找不到对应的库。

四、maven打包命令:

公共资源jar包发布到maven私服命令如下:
mvn clean deploy

扩展知识点:

package命令完成了项目编译、单元测试、打包功能,但没有把打好的可执行jar包(war包或其它形式的包)布署到本地maven仓库和远程maven私服仓库
install命令完成了项目编译、单元测试、打包功能,同时把打好的可执行jar包(war包或其它形式的包)布署到本地maven仓库,但没有布署到远程maven私服仓库

1
2
3
4
mvn install:install-file -DgroupId=org.xl.brave  
-DartifactId=brave-axis2 -Dversion=0.0.1
-Dfile=C:\Users\sy\Desktop\brave-axis2-0.0.1-SNAPSHOT.jar
-Dpackaging=jar

deploy命令完成了项目编译、单元测试、打包功能,同时把打好的可执行jar包(war包或其它形式的包)布署到本地maven仓库和远程maven私服仓库

1
2
3
4
5
mvn deploy:deploy-file -Dmaven.test.skip=true \
-Dfile=D:\workspace\com.xxx.test-1.0.0.jar \
-DgroupId=com.xxx -DartifactId=test -Dversion=1.0.0-SNAPSHOT -Dpackaging=jar
-DrepositoryId=snapshots
-Durl=http://ip:8081/repository/maven-releases/
1
2
3
4
5
6
7
8
9
命令解释:
mvn deploy:deploy-file 安装到远程仓库的maven命令
-Dfile=jar包的位置
-DgroupId=groupId,自定义
-DartifactId=artifactId,自定义
-Dversion=version,自定义
-Durl=私服仓库地址
-Dpackaging=jar
-DrepositoryId=仓库id

四)maven几种打包插件介绍

1.spring-boot-maven-plugin

spring-boot-maven-plugin:springboot项目默认的打包工具,默认情况下只会将项目源码编译生成的class文件和资源文件依赖jar包都打进来,即打包自己项目的class文件+环境变量+静态资源文件+依赖jar(不会把依赖jar反编译为class文件打入)。使用2.2.1.RELEASE版本需要maven版本在2.0及以上,JDK在1.8及以上。

1
2
3
4
5
6
7
8
<build>
<plugins>
<plugin>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-maven-plugin</artifactId>
</plugin>
</plugins>
</build>

2.maven-shade-plugin

它很聪明地将依赖的JAR文件全部解压后,再将得到的.class文件连同当前项目的.class文件一起合并到最终的CLI包(可以直接运行的jar包)中,这样,在执行CLI JAR文件的时候,所有需要的类就都在Classpath中了。

maven-shade-plugin提供了两大基本功能:
将依赖的jar包打包到当前jar包(常规打包是不会将所依赖jar包打进来的);
对依赖的jar包进行重命名(用于类的隔离);

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
<plugin>
<groupId>org.apache.maven.plugins</groupId>
<artifactId>maven-shade-plugin</artifactId>
<version>3.2.4</version>
<configuration>
<!-- put your configurations here -->
</configuration>
<executions>
<execution>
<phase>package</phase>
<goals>
<goal>shade</goal>
</goals>
</execution>
</executions>
</plugin>

3.maven-assembly-plugin

功能非常强大,是maven中针对打包任务而提供的标准插件。它是Maven最强大的打包插件,它支持各种打包文件格式,包括zip、tar.gz、tar.bz2等等,通过一个打包描述文件设置(src/main/assembly.xml),它能够帮助用户选择具体打包哪些资源文件集合、依赖、模块,甚至本地仓库文件,每个项的具体打包路径用户也能自由控制。

它不是把依赖的jar直接打进去,而是把依赖的jar编译成class文件打入jar中目录

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
<plugin>
<artifactId>maven-assembly-plugin</artifactId>
<configuration>
<archive>
<manifest>
<mainClass>com.example.demo.DemoApplication</mainClass>
</manifest>
</archive>
<descriptorRefs>
<descriptorRef>jar-with-dependencies</descriptorRef>
</descriptorRefs>
</configuration>
<!--下面是为了使用 mvn package命令,如果不加则使用mvn assembly-->
<executions>
<execution>
<id>make-assemble</id>
<!-- 绑定到package生命周期 -->
<phase>package</phase>
<goals>
<!-- 只运行一次 -->
<goal>single</goal>
</goals>
</execution>
</executions>
</plugin>

4.maven-jar-plugin

默认的打包方式,用来打普通的project JAR包

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
<plugin>
<groupId>org.apache.maven.plugins</groupId>
<artifactId>maven-jar-plugin</artifactId>
<version>3.2.2</version>
<configuration>
<!--要使用的打包配置.-->
<archive>
<!-- 创建的归档文件是否包含以下pom.xml 和pom.properties Maven 文件,默认是true -->
<addMavenDescriptor>true</addMavenDescriptor>
<!-- 生成MANIFEST.MF的设置 -->
<manifest>
<!-- 为依赖包添加路径, 这些路径会写在MANIFEST文件的Class-Path下 -->
<addClasspath>true</addClasspath>
<!-- 这个jar所依赖的jar包添加classPath的时候的前缀,如果这个jar本身和依赖包在同一级目录,则不需要添加 -->
<classpathPrefix>lib/</classpathPrefix>
<!-- jar启动入口类 -->
<mainClass>com.example.demo.DemoApplication</mainClass>
</manifest>
<manifestEntries>
<!-- 在Class-Path下添加配置文件的路径 -->
<!--<Class-Path>../config/</Class-Path>-->
</manifestEntries>
</archive>
<!-- jar包的位置,其中${project.build.directory}默认为 target/ -->
<outputDirectory>${project.build.directory}</outputDirectory>
<!--过滤掉不希望包含在jar中的文件-->
<excludes>
<exclude>${project.basedir}/xml/*</exclude>
</excludes>
<!--要包含的文件列表-->
<includes>
<!-- 打jar包时,打包class文件和config目录下面的 properties文件 -->
<!-- 有时候可能需要一些其他文件,这边可以配置,包括剔除的文件等等 -->
<include>**/*.class</include>
<include>**/*.properties</include>
</includes>
</configuration>
</plugin>

5.maven-dependency-plugin

maven-dependency-plugin是处理与依赖相关的插件。它有很多可用的goal,大部分是和依赖构建、分析和解决相关的goal,这部分goal可以直接用maven的命令操作,
例如:mvn dependency:tree、mvn dependency:analyze
但是我们最常用到的是dependency:copydependency:copy-dependencies、dependency:unpack、dependency:unpack-dependencies这四个。

maven-dependency-plugin最大的用途是帮助分析项目依赖,dependency:list能够列出项目最终解析到的依赖列表,dependency:tree能进一步的描绘项目依赖树,dependency:analyze可以告诉你项目依赖潜在的问题,如果你有直接使用到的却未声明的依赖,该目标就会发出警告。
maven-dependency-plugin还有很多目标帮助你操作依赖文件,例如dependency:copy-dependencies能将项目依赖从本地Maven仓库复制到某个特定的文件夹下面。
默认的主资源文件目录是src/main/resources,很多用户会需要添加额外的资源文件目录,这个时候就可以通过配置maven-resources-plugin来实现。
此外,资源文件过滤也是Maven的一大特性,你可以在资源文件中使用_${propertyName}_形式的Maven属性,然后配置maven-resources-plugin开启对资源文件的过滤,之后就可以针对不同环境通过命令行或者Profile传入属性的值,以实现更为灵活的构建。

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
<!--在打包阶段将依赖的jar包导出到lib目录下-->
<plugin>
<groupId>org.apache.maven.plugins</groupId>
<artifactId>maven-dependency-plugin</artifactId>
<executions>
<execution>
<id>copy-dependencies</id>
<phase>package</phase>
<goals>
<goal>copy-dependencies</goal>
</goals>
<configuration>
<type>jar</type>
<includeTypes>jar</includeTypes>
<!--项目构件输出目录,其中${project.build.directory}默认为 target/-->
<outputDirectory>${project.build.directory}/lib</outputDirectory>
<overWriteReleases>false</overWriteReleases>
<overWriteSnapshots>false</overWriteSnapshots>
<overWriteIfNewer>true</overWriteIfNewer>
</configuration>
</execution>
</executions>
</plugin>

6.maven-resources-plugin

为了使项目结构更为清晰,Maven区别对待Java代码文件和资源文件,maven-compiler-plugin用来编译Java代码,maven-resources-plugin则用来处理资源文件。
默认的主资源文件目录是src/main/resources,很多用户会需要添加额外的资源文件目录,这个时候就可以通过配置maven-resources-plugin来实现。
此外,资源文件过滤也是Maven的一大特性,你可以在资源文件中使用_${propertyName}_形式的Maven属性,然后配置maven-resources-plugin开启对资源文件的过滤,之后就可以针对不同环境通过命令行或者Profile传入属性的值,以实现更为灵活的构建。

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
<plugin>
<groupId>org.apache.maven.plugins</groupId>
<artifactId>maven-resources-plugin</artifactId>
<version>3.2.0</version>
<executions>
<execution>
<id>copy-resources</id>
<!--绑定到package生命周期-->
<phase>package</phase>
<goals>
<goal>copy-resources</goal>
</goals>
<configuration>
<outputDirectory>target/conf</outputDirectory>
<useDefaultDelimiters>false</useDefaultDelimiters>
<includeEmptyDirs>true</includeEmptyDirs>
<!--设置自定义分隔符-->
<delimiters>
<delimiter>#</delimiter>
</delimiters>
<resources>
<resource>
<!--从此目录下读取全部以.properties和.xml开头的文件-->
<directory>src/main/resources/</directory>
<!--用来指定需要打入哪些后缀类型的文件-->
<!--<includes>
<include>**/*.properties</include>
<include>**/*.xml</include>
</includes>-->
</resource>
</resources>
<!-- 过滤后缀为crt和jks的文件 -->
<nonFilteredFileExtensions>
<nonFilteredFileExtension>crt</nonFilteredFileExtension>
<nonFilteredFileExtension>jks</nonFilteredFileExtension>
</nonFilteredFileExtensions>
</configuration>
</execution>
</executions>
</plugin>

7.maven-compiler-plugin

作用: 1. 指示maven用什么版本的jdk编译; 2. 指示IntelliJ IDEA把项目识别成什么jdk

maven 是个管理工具,如果我们不告诉它我们的代码要使用什么样的 jdk 版本编译的话,它就会用 maven-compiler-plugin 默认的 jdk 版本来进行处理,这样就容易出现版本不匹配,以至于可能导致编译不通过的问题。
maven-compiler-plugin插件是一个Maven插件,用来编译项目代码;自从3.0开始默认的编译器是javax.tools.JavaCompiler,用来编译Java源码;如果你想强制插件使用javac编译器,你必须配置插件的属性forceJavacCompilerUse;还要注意,当前默认源(source)设置为1.6,默认目标(target)设置为1.6。独立运行Maven和JDK,可以通过source和target选项更改他们的默认值;

1
2
3
4
5
6
7
8
9
10
11
12
13
14
<build>
<plugins>
<plugin>
<groupId>org.apache.maven.plugins</groupId>
<artifactId>maven-compiler-plugin</artifactId>
<version>3.8.0</version>
<configuration>
<source>1.8</source>
<target>1.8</target>
<encoding>UTF-8</encoding>
</configuration>
</plugin>
</plugins>
</build>

Maven知识记录
https://vegetablest.github.io/2022/08/03/Maven知识记录/
作者
af su
发布于
2022年8月3日
许可协议