Skip to content

Maven

安装

1、下载解压安装至不含中文目录:Maven – Download Apache Maven

2、配置环境变量:设置——系统——系统信息——高级系统设置——环境变量

shell
# 系统环境添加,路径为Maven安装目录
MAVEN_HOME  D:\software\apache-maven-3.6.3

# path中添加变量
%MAVEN_HOME%\bin

3、文件配置

xml
<!--conf/settings.xml-->
<localRepository>选择本地目录作为依赖存储位置(最好别带中文)</localRepository>

<!--在mirrors添加一下子结构,指定阿里镜像源-->
<mirror>  
    <id>alimaven</id>  
    <name>aliyun maven</name>  
    <url>http://maven.aliyun.com/nexus/content/groups/public/</url>
    <mirrorOf>central</mirrorOf>          
</mirror>

4、idea进行如下配置

Maven使用

基本概述

依赖管理

通过网站查找对应依赖:依赖查找,复制粘贴至pom文件下的dependencies作为其子标签,刷新Maven。

导入的依赖储存在<localRepository>指定的目录下,具体位置由groupId、artifactId、version组成,以下方依赖为例,其储存在:本地仓库目录/org/springframework/spring-web/5.1.8.RELEASE。

xml
<dependencies>
    <dependency>
        <groupId>org.springframework</groupId>
        <artifactId>spring-web</artifactId>
        <version>5.1.8.RELEASE</version>
    </dependency>
</dependencies>

依赖范围

在scope中指定依赖的使用范围,默认为compile,仅在测试环境中使用的设置为test,运行环境中已有的依赖设置为provided。了解即可,从依赖网站查找的依赖一般都指定了该值,直接使用即可。

xml
<dependency>
    <groupId>some.group</groupId>
    <artifactId>some-artifact</artifactId>
    <version>1.0</version>
    <!--仅在插件使用该依赖-->
    <scope>plugin</scope>
</dependency>
依赖范围编译环境测试环境运行环境
compile生效生效生效
provided生效生效不生效
system生效生效不生效
runtime不生效生效生效
test不生效生效不生效

工作流程

jar包查找流程:本地仓库——私服仓库——中央仓库,查找到就将依赖载入到当前工程的External Libraries如果在私服/中央仓库查找到依赖,还会将其下载至本地仓库

核心生命周期

同一生命周期内,执行后面的命令,前面的所有命令会自动执行,如执行install会从Validate开始执行直到install

clean:清除当前工程编译后生成的文件(即删除target整个目录);

validate:对工程进行基础验证,如工程结构、pom、资源文件等是否正确;

compile:对src/main/java目录下的源码进行编译(会生成target目录);

test:编译并执行src/test/java/目录下的所有测试用例;

package:将当前项目打包,普通项目打jar包,webapp项目打war包;

verify:验证工程所有代码、配置进行是否正确,如类中代码的语法检测等;

install:将当前工程打包,然后安装到本地仓库,别人可通过GAV导入;

site:生成项目的概述、源码测试覆盖率、开发者列表等站点文档(需要额外配置);

deploy:将当前工程对应的包,上传到远程仓库,提供给他人使用(私服会用)。

依赖冲突

依赖的传递性:当引入的一个包,如果依赖于其他包(类库),当前的工程就必须再把其他包引入进来

自动解决依赖冲突

  • 层级优先原则:不同层级出现依赖冲突,会先剔除深优先级的依赖,即层级越浅,优先级越高。
  • 声明优先原则:相同层级出现依赖冲突(版本相同),先配置的会覆盖后配置的,即后者会被剔除。
  • 配置优先原则:相同层级出现依赖冲突(版本不同),后配置的会覆盖先配置的,即前者会被剔除。

手动解决依赖冲突

通过<exclusion>可以排除当前依赖的子依赖

xml
<dependency>
    <groupId>org.springframework</groupId>
    <artifactId>spring-web</artifactId>
    <version>5.1.8.RELEASE</version>
    <exclusions>
        <!-- 排除web包依赖的beans包 -->
        <exclusion>
            <groupId>org.springframework</groupId>
            <artifactId>spring-beans</artifactId>
        </exclusion>
    </exclusions>
</dependency>

聚合工程

  • 父工程:不具备任何代码、仅有pom.xml的空项目,用来定义公共依赖、插件和配置。
  • 子工程:编写具体代码的子项目,可以继承父工程的配置、依赖项,还可以独立拓展。

Maven聚合工程创建

1、创建Maven父工程,删除src目录,在其pom文件中配置打包方式为pom

xml
<packaging>pom</packaging>

2、在父工程下创建子工程。idea对于Maven父子工程,在父工程进行构建,会对子工程进行统一构建

xml
<!--在父工程pom.xml下会出现module标签,显示其存在的子工程名-->
<modules></modules>

<!--在子工程pom.xml下会出现parent标签,显示其父工程信息-->
<parent></parent>

3、跳过测试

可以在pom文件中指定要排除/跳过的测试用例

xml
<build>
    <plugins>
        <plugin>
            <artifactId>maven-surefire-plugin</artifactId>
            <version>2.22.1</version>
            <configuration>
                <skipTests>true</skipTests>
                <includes>
                    <!-- 指定要执行的测试用例 -->
                    <include>**/XXX*Test.java</include>
                </includes>
                <excludes>
                    <!-- 执行要跳过的测试用例 -->
                    <exclude>**/XXX*Test.java</exclude>
                </excludes>
            </configuration>
        </plugin>
    </plugins>
</build>

也可以通过idea跳过所有测试

SpringBoot Maven聚合工程创建

1、创建一个SpringBoot项目,删除src模块,设置打包方式为pom

xml
<packaging>pom</packaging>

<!--指定子项目模块-->
<modules>
    <module>son</module>
</modules>

2、在父项目下创建子项目(SpringBoot项目),将默认的parent设置为自己创建的父工程

xml
<parent>
    <groupId>com.fjut</groupId>
    <artifactId>parent</artifactId>
    <version>0.0.1-SNAPSHOT</version>
</parent>

聚合工程依赖管理

  • <dependencies>:定义强制性依赖,写在该标签里的依赖项,子工程必须强制继承

  • <dependencyManagement>:定义可选性依赖,该标签里的依赖项,子工程可选择使用。子工程在使用<dependencyManagement>中已有的依赖项时,不需要写<version>版本号

    xml
    <!--在properties统一配置版本-->
    <properties>
        <spring.version>5.2.0.RELEASE</spring.version>
    </properties>
    
    <!--在依赖中通过${}引用-->
    <dependencyManagement>
        <dependency>
            <groupId>org.springframework</groupId>
            <artifactId>spring-aop</artifactId>
            <version>${spring.version}</version>
        </dependency>
    </dependencyManagement>

聚合工程依赖冲突

工程001引用依赖A,将其打包安装引入到工程002,因为依赖传递,此时依赖A也会被引入到工程002。

如果依赖A发生冲突,设置optional为true即可使依赖A不传递到工程002.

  • true:开启隐藏,当前依赖不会向其他工程传递,只保留给自己用;
  • false:默认值,表示当前依赖会保持传递性,其他引入当前工程的项目会间接依赖。
xml
<dependency>
    <groupId>org.springframework</groupId>
    <artifactId>spring-aop</artifactId>
    <version>5.1.8.RELEASE</version>
    <optional>true</optional>
</dependency>

父工程的依赖传递

项目需要用到Spring-Cloud-Alibaba的多个依赖项,将他们全部定义在父POM<dependencyManagement>标签里,然后子工程按需引入,但这样可能会导致pom文件冗余。

xml
<!--在父工程中通过dependencyManagement设置,子依赖项引入-->
<dependencyManagement>
    <dependency>
        <groupId>com.alibaba.cloud</groupId>
        <artifactId>spring-cloud-starter-alibaba-sentinel</artifactId>
    </dependency>

    <dependency>
        <groupId>com.alibaba.cloud</groupId>
        <artifactId>spring-cloud-starter-alibaba-nacos-config</artifactId>
    </dependency>
    
    ………………………………
</dependencyManagement>

另一种方法是,在父工程中引入Spring-Cloud-Alibaba所有依赖项的父依赖 spring-cloud-alibaba-dependencies,并将scope设置为import,配合<type>pom</type>,作用是把spring-cloud-alibaba-dependencies的所有子依赖,作为当前项目的可选依赖向下传递

xml
<!--父工程-->
<dependencyManagement>
   <dependency>
        <groupId>com.alibaba.cloud</groupId>
        <artifactId>spring-cloud-alibaba-dependencies</artifactId>
        <version>${spring-cloud-alibaba.version}</version>
        <type>pom</type>
        <scope>import</scope>
    </dependency>
</dependencyManagement>


<!--子工程按需引入,不要直接引入整个spring-cloud-alibaba-dependencies-->
<dependency>
    <groupId>com.alibaba.cloud</groupId>
    <artifactId>spring-cloud-starter-alibaba-sentinel</artifactId>
</dependency>

<dependency>
    <groupId>com.alibaba.cloud</groupId>
    <artifactId>spring-cloud-starter-alibaba-nacos-config</artifactId>
</dependency>

Maven属性

类型使用方式
Maven内置属性(可以在properties标签中自定义)${属性名},如${version}
项目环境属性${setting.属性名},如${settings.localRepository}
Java环境变量${xxx.属性名},如${java.class.path}
系统环境变量${env.属性名},如${env.USERNAME}

多环境配置

针对SpringBoot聚合项目,用于多环境切换

1、在父项目中进行如下配置

xml
<profiles>
    <!-- 开发环境 -->
    <profile>
        <id>dev</id>
        <properties>
            <profile.active>dev</profile.active>
        </properties>
    </profile>
    
    <!-- 生产环境 -->
    <profile>
        <id>prod</id>
        <properties>
            <profile.active>prod</profile.active>
        </properties>
        <!-- activeByDefault=true,表示打包时,默认使用这个环境 -->
        <activation>
            <activeByDefault>true</activeByDefault>
        </activation>
    </profile>
    
    <!-- 测试环境 -->
    <profile>
        <id>test</id>
        <properties>
            <profile.active>test</profile.active>
        </properties>
    </profile>
</profiles>

<!-- 开启 yml 文件的 ${} 取值支持 -->
<dependency>
    <groupId>org.springframework.boot</groupId>
    <artifactId>spring-boot-configuration-processor</artifactId>
    <version>2.1.5.RELEASE</version>
    <optional>true</optional>
</dependency>

<!-- 添加插件,将项目的资源文件复制到输出目录中 -->
<plugin>
    <groupId>org.apache.maven.plugins</groupId>
    <artifactId>maven-resources-plugin</artifactId>
    <version>3.2.0</version>
    <configuration>
        <encoding>UTF-8</encoding>
        <useDefaultDelimiters>true</useDefaultDelimiters>
    </configuration>
</plugin>

2、在子项目中

properties
# 设置启用的环境,从pom配置文件中读取,而不是写死,所以只需要修改父项目的pom文件(修改完后需要刷新Maven),所有子项目的启用环境都会修改

spring:
  profiles:
    active: ${profile.active}

Nexus私服搭建

Nexus安装

1、下载安装

官网下载(或网络查找,通过网盘下载):Download (sonatype.com)安装目录不能存在中文,否则会报错

软件的目录结构如下:

  • nexus-x.x.x-xx:里面会放Nexus启动时所需要的依赖、环境配置;
  • sonatype-work:存放Nexus运行时的工作数据,如存储上传的jar包等

2、基本配置

配置文件目录:安装目录\nexus-3.54.1-01\etc\nexus-default.properties,可以进行端口号等配置

启动文件目录:安装目录\nexus-3.54.1-01\bin,进入目录,通过命令行执行:nexus.exe /run nexus启动

  • 启动后通过下方链接访问http://localhost:8081

3、登录并修改默认密码

启动后,在Nexus页面右上角登录,账号为admin,而密码生成在:安装目录\sonatype-work\nexus\sonatype-work\nexus3\admin.password。登录后根据提示修改密码即可。

Nexus结构

仓库类型

类型释义作用
hosted宿主仓库保存中央仓库中没有的资源,如自研组件
proxy代理仓库配置中央仓库,即镜像源,私服中没有时会去这个地址拉取
group仓库组用来对宿主、代理仓库分组,将多个仓库组合成一个对外服务
virtual虚拟仓库并非真实存在的仓库,类似于MySQL中的视图

内置仓库

名称作用
maven-centralNexus 对 Maven 中央仓库的代理
maven-publicNexus 默认创建,供开发人员下载使用的组仓库。
maven-releasseNexus 默认创建,供开发人员部署自己 jar 包的宿主仓库,要求 releasse 版本
maven-snapshotsNexus 默认创建,供开发人员部署自己 jar 包的宿主仓库,要求 snapshots 版本。

原文链接:https://blog.csdn.net/Be_racle/article/details/136462230

使用配置

1、修改Maven settings.xml配置文件

xml
<!--将Maven的镜像源设置为自己私服地址-->
<mirror>
    <id>nexus-zhuzi</id>
    <mirrorOf>*</mirrorOf>
    <url>http://localhost:8081/repository/maven-public/</url>
</mirror>
<!--如果没有允许匿名访问,则还需下方配置,id需要和mirror中配置相同-->
<server>
  <id>nexus-zhuzi</id>
  <username>admin</username>
  <password>@123456</password>
</server>

2、Nexus中修改访问权限

Nexus权限体系为:权限——角色——用户,在Security中可以根据需求创建

3、Nexus配置远程仓库

配置完需要滑到最下方保存

shell
# 镜像源修改为阿里云镜像
http://maven.aliyun.com/nexus/content/groups/public/

4、Nexus创建仓库

建议Release、Snapshot格式的仓库各自创建一个

  • Release:稳定版,表示存放可以稳定使用的版本仓库;
  • Snapshot:快照版,代表存储开发阶段的版本仓库;
  • Mixed:混合版,不区分格式,表示混合存储代码的仓库。

5、pom文件配置

配置完成后,使用deploy即可部署到Nexus中,结尾是SNAPSHOT,所以会被发布到快照仓库,如果结尾不是这个后缀时,就会被发布到Release仓库

发布的包不能带有上级,即不能有parent依赖,否则在其他人在拉取该项目时,会找不到其父项目而构建失败。要解决这个问题,可以先将parent项目打包并上传至远程仓库,然后再发布依赖于该parent项目的子模块。

xml
<!-- Maven的setting.xml中配置 -->
<!--配置在servers下-->
<server>
  <!--用于匹配distributionManagement中的id-->
  <id>zhuzi-release</id>
  <username>admin</username>
  <password>Nexus密码</password>
</server>

<server>
  <id>zhuzi-snapshot</id>
  <username>admin</username>
  <password>Nexus密码</password>
</server>
xml
<!-- 配置当前工程,在私服中保存的具体位置 -->
<distributionManagement>
    <repository>
        <!-- 这里对应之前 settings.xml 里配置的server-id -->
        <id>zhuzi-release</id>
        <!-- 这里代表私服仓库的地址,大家只需要把后面的名字换掉即可 -->
        <url>http://localhost:8081/repository/zhuzi-release/</url>
    </repository>
    <snapshotRepository>
        <id>zhuzi-snapshot</id>
        <url>http://localhost:8081/repository/zhuzi-snapshot/</url>
    </snapshotRepository>
</distributionManagement>

Nexus仓库组

Members区域代表当前仓库组的成员,而这些成员会按照你排列的顺序,具备不同的优先级,越靠前的优先级越高(hosted宿主仓库必须在proxy代理仓库前)

单工程与仓库组映射配置

仅针对当前maven工程

xml
<!--pom.xml中进行下方配置-->

<!--普通依赖的仓库组地址,针对于<dependency>标签生效-->
<repositories>
    <repository>
        <id>zhuzi-group</id>
        <!-- 配置仓库组的地址 -->
        <url>http://localhost:8081/repository/zhuzi-group/</url>
        <!-- 允许从中拉取稳定版的依赖 -->
        <releases>
            <enabled>true</enabled>
        </releases>
        <!-- 也允许从中拉取快照版的依赖 -->
        <snapshots>
            <enabled>true</enabled>
        </snapshots>
    </repository>
</repositories>

<!--插件依赖的仓库组地址,针对于<plugin>标签生效-->
<pluginRepositories>
    <pluginRepository>
        <id>plugin-group</id>
        <url>http://localhost:8081/repository/zhuzi-group/</url>
        <releases>
            <enabled>true</enabled>
        </releases>
        <snapshots>
            <enabled>true</enabled>
        </snapshots>
    </pluginRepository>
</pluginRepositories>

Maven与仓库组映射配置

针对所有Maven工程

<updatePolicy>标签: 如果本地仓库没有,则从配置的远程仓库下载这时会根据<updatePolicy>策略来决定是否需要从远程仓库下载依赖。

  • always:每次需要Maven依赖时,都先尝试从远程仓库下载最新的依赖项;
  • daily:每天首次使用某个依赖时,从远程仓库中下载一次依赖项;
  • interval:X:每隔X个小时,下载一次远程仓库的依赖,X只能是整数;
  • never:仅使用本地仓库中已经存在的依赖项,不尝试从远程仓库中拉取。
xml
<!--Maven setting.xml中进行下方配置-->
<profile>
	<id>zhuzi-group</id>
	<repositories>
		<repository>
			<id>nexus-maven</id>
			<url>http://localhost:8081/repository/zhuzi-group/</url>
			<releases>
				<enabled>true</enabled>
				<updatePolicy>always</updatePolicy>
			</releases>
			<snapshots>
				<enabled>true</enabled>
				<updatePolicy>always</updatePolicy>
			</snapshots>
		</repository>
	</repositories>
 
	<pluginRepositories>
		<pluginRepository>
			<id>nexus-maven</id>
			<url>http://localhost:8081/repository/zhuzi-group/</url>
			<releases>
				<enabled>true</enabled>
				<updatePolicy>always</updatePolicy>
			</releases>
			<snapshots>
				<enabled>true</enabled>
				<updatePolicy>always</updatePolicy>
			</snapshots>
		</pluginRepository>
	</pluginRepositories>
</profile>


<!--激活上述配置-->
<activeProfiles>
    <!-- 这里写前面配置的ID -->
	<activeProfile>zhuzi-group</activeProfile>
</activeProfiles>