【Maven】基于IDEA学习 Maven依赖 与 工程继承、聚合关系

文章目录

一、基于IDEA 进行Maven依赖管理

1. 依赖管理概念

Maven 的依赖管理是 Maven 软件的一个核心功能之一,能够帮助开发人员自动解决软件包依赖问题 ,简化了开发过程中的工作,避免出现版本冲突和依赖缺失等问题。

通过定义 POM 文件,Maven 能够自动解析项目的依赖关系 ,并通过 Maven 仓库自动下载和管理依赖,从而避免了手动下载和管理依赖的繁琐工作和可能引发的版本冲突问题。

2. Maven工程核心信息配置和解读(GAVP)

xml 复制代码
<!-- 模型版本 -->
<modelVersion>4.0.0</modelVersion>
<!-- 公司或者组织的唯一标志,并且配置时生成的路径也是由此生成, 如com.companyname.project-group,maven会将该项目打成的jar包放本地路径:/com/companyname/project-group -->
<groupId>com.companyname.project-group</groupId>
<!-- 项目的唯一ID,一个groupId下面可能多个项目,就是靠artifactId来区分的 -->
<artifactId>project</artifactId>
<!-- 版本号 -->
<version>1.0.0</version>

<!--打包方式
    默认:jar
    jar指的是普通的java项目打包方式! 项目打成jar包!
    war指的是web项目打包方式!项目打成war包!
    pom不会讲项目打包!这个项目作为父工程,被其他工程聚合或者继承!后面会讲解两个概念
-->
<packaging>jar/pom/war</packaging>

3. Maven工程依赖管理配置

依赖管理和依赖添加

xml 复制代码
<!-- 
   通过编写依赖jar包的gav必要属性,引入第三方依赖!
   scope属性是可选的,可以指定依赖生效范围!
   依赖信息查询方式:
      1. maven仓库信息官网 https://mvnrepository.com/
      2. mavensearch插件搜索
 -->
<dependencies>
    <!-- 引入具体的依赖包 -->
    <dependency>
        <groupId>log4j</groupId>
        <artifactId>log4j</artifactId>
        <version>1.2.17</version>
        <!-- 依赖范围 -->
        <scope>runtime</scope>
    </dependency>

</dependencies>

依赖版本统一提取和维护

xml 复制代码
<!--声明版本-->
<properties>
  <!--命名随便,内部制定版本号即可!-->
  <junit.version>4.12</junit.version>
  <!-- 也可以通过 maven规定的固定的key,配置maven的参数!如下配置编码格式!-->
  <project.build.sourceEncoding>UTF-8</project.build.sourceEncoding>
  <project.reporting.outputEncoding>UTF-8</project.reporting.outputEncoding>
</properties>

<dependencies>
  <dependency>
    <groupId>junit</groupId>
    <artifactId>junit</artifactId>
    <!--引用properties声明版本 -->
    <version>${junit.version}</version>
  </dependency>
</dependencies>

4. 依赖范围

通过设置坐标的依赖范围(scope),可以设置 对应jar包的作用范围:编译环境、测试环境、运行环境

依赖范围 描述
compile 编译依赖范围,scope 元素的缺省值。使用此依赖范围的 Maven 依赖,对于三种 classpath 均有效,即该 Maven 依赖在上述三种 classpath 均会被引入。例如,log4j 在编译、测试、运行过程都是必须的。
test 测试依赖范围。使用此依赖范围的 Maven 依赖,只对测试 classpath 有效。例如,Junit 依赖只有在测试阶段才需要。
provided 已提供依赖范围。使用此依赖范围的 Maven 依赖,只对编译 classpath 和测试 classpath 有效。例如,servlet-api 依赖对于编译、测试阶段而言是需要的,但是运行阶段,由于外部容器已经提供,故不需要 Maven 重复引入该依赖。
runtime 运行时依赖范围。使用此依赖范围的 Maven 依赖,只对测试 classpath、运行 classpath 有效。例如,JDBC 驱动实现依赖,其在编译时只需 JDK 提供的 JDBC 接口即可,只有测试、运行阶段才需要实现了 JDBC 接口的驱动。
system 系统依赖范围,其效果与 provided 的依赖范围一致。其用于添加非 Maven 仓库的本地依赖,通过依赖元素 dependency 中的 systemPath 元素指定本地依赖的路径。鉴于使用其会导致项目的可移植性降低,一般不推荐使用。
import 导入依赖范围,该依赖范围只能与 dependencyManagement 元素配合使用,其功能是将目标 pom.xml 文件中 dependencyManagement 的配置导入合并到当前 pom.xml 的 dependencyManagement 中。

5. Maven工程依赖下载失败错误解决

在使用 Maven 构建项目时,可能会发生依赖项下载错误的情况,解决方案:

  1. 检查网络连接和 Maven 仓库服务器状态。

  2. 确保依赖项的版本号与项目对应的版本号匹配,并检查 POM 文件中的依赖项是否正确。

  3. 清除本地 Maven 仓库缓存(lastUpdated 文件) ,因为只要存在lastupdated缓存文件,刷新也不会重新下载。本地仓库中,根据依赖的gav属性依次向下查找文件夹,最终删除内部的文件,刷新重新下载即可!

    例如: pom.xml依赖

    xml 复制代码
    <dependency>
      <groupId>com.alibaba</groupId>
      <artifactId>druid</artifactId>
      <version>1.2.8</version>
    </dependency>

或者可以将清除lastUpdated文件 的操作写在一个脚本文件中,手动创建文件"clearLastUpdated.bat",名字任意,但是后缀必须是bat,将以下内容复制到文件中

bat 复制代码
cls 
@ECHO OFF 
SET CLEAR_PATH=D: 
SET CLEAR_DIR=D:\maven-repository(本地仓库路径)
color 0a 
TITLE ClearLastUpdated For Windows 
GOTO MENU 
:MENU 
CLS
ECHO. 
ECHO. * * * *  ClearLastUpdated For Windows  * * * * 
ECHO. * * 
ECHO. * 1 清理*.lastUpdated * 
ECHO. * * 
ECHO. * 2 查看*.lastUpdated * 
ECHO. * * 
ECHO. * 3 退 出 * 
ECHO. * * 
ECHO. * * * * * * * * * * * * * * * * * * * * * * * * 
ECHO. 
ECHO.请输入选择项目的序号: 
set /p ID= 
IF "%id%"=="1" GOTO cmd1 
IF "%id%"=="2" GOTO cmd2 
IF "%id%"=="3" EXIT 
PAUSE 
:cmd1 
ECHO. 开始清理
%CLEAR_PATH%
cd %CLEAR_DIR%
for /r %%i in (*.lastUpdated) do del %%i
ECHO.OK 
PAUSE 
GOTO MENU 
:cmd2 
ECHO. 查看*.lastUpdated文件
%CLEAR_PATH%
cd %CLEAR_DIR%
for /r %%i in (*.lastUpdated) do echo %%i
ECHO.OK 
PAUSE 
GOTO MENU 

6. Maven工程Build构建配置

项目构建是指将源代码、依赖库和资源文件等转换成可执行或可部署的应用程序的过程,包括编译源代码、链接依赖库、打包和部署等多个步骤。

我们可以在pom.xml定制一些配置,来修改默认构建【在pom.xml / build标签中指定】的行为和产物!

指定打包命名

xml 复制代码
<!-- 默认的打包名称:artifactid+verson.打包方式 -->
<build>
  <finalName>定义打包名称</finalName>
</build>  

指定打包文件

  • 在java文件夹中添加java类 ,会自动打包编译到classes文件夹下
  • 在java文件夹中添加xml文件 ,默认不会被打包
  • 默认情况下,按照maven工程结构放置的文件会默认被编译和打包

除此之外、我们可以使用resources标签,指定要打包资源的文件夹要把哪些静态资源打包到 classes根目录下!

例如:不被打包

xml 复制代码
<build>
    <!--设置要打包的资源位置-->
    <resources>
        <resource>
            <!--设置资源所在目录-->
            <directory>src/main/java</directory>
            <includes>
                <!--设置包含的资源类型-->
                <include>**/*.xml</include>
            </includes>
        </resource>
    </resources>
</build>

配置依赖插件

dependencies标签下引入开发需要的jar包!我们可以在build/plugins/plugin标签引入插件!

常用的插件:修改jdk版本、tomcat插件、mybatis分页插件、mybatis逆向工程插件等等!

xml 复制代码
<build>
  <plugins>
      <!-- java编译插件,配jdk的编译版本 -->
      <plugin>
        <groupId>org.apache.maven.plugins</groupId>
        <artifactId>maven-compiler-plugin</artifactId>
        <configuration>
          <source>1.8</source>
          <target>1.8</target>
          <encoding>UTF-8</encoding>
        </configuration>
      </plugin>
      <!-- tomcat插件 -->
      <plugin>
        <groupId>org.apache.tomcat.maven</groupId>
        <artifactId>tomcat7-maven-plugin</artifactId>
         <version>2.2</version>
          <configuration>
          <port>8090</port>
          <path>/</path>
          <uriEncoding>UTF-8</uriEncoding>
          <server>tomcat7</server>
        </configuration>
      </plugin>
    </plugins>
</build>

二、Maven依赖传递和依赖冲突

1. Maven依赖传递特性

概念

假如有Maven项目A,项目B依赖A,项目C依赖B。那么我们可以说 C依赖A。也就是说,依赖的关系为:C--->B--->A, 那么我们执行项目C时,会自动把B、A都下载导入到C项目的jar包文件夹中,这就是依赖的传递性。

作用

  • 简化依赖导入过程
  • 确保依赖版本正确

传递的原则

在 A 依赖 B,B 依赖 C 的前提下,C 是否能够传递到 A,取决于 B 依赖 C 时使用的依赖范围以及配置

  • B 依赖 C 时使用 compile 范围:可以传递

  • B 依赖 C 时使用 test 或 provided 范围:不能传递,所以需要这样的 jar 包时,就必须在需要的地方明确配置依赖才可以。

  • B 依赖 C 时,若配置了以下标签,则不能传递

    xml 复制代码
    <dependency>
        <groupId>com.alibaba</groupId>
        <artifactId>druid</artifactId>
        <version>1.2.15</version>
        <optional>true</optional>
    </dependency>

依赖传递终止

  • 非compile范围进行依赖传递
  • 使用optional配置终止传递
  • 依赖冲突(传递的依赖已经存在)

2. Maven依赖冲突特性

当直接引用或者间接引用出现了相同的jar包! 这时呢,一个项目就会出现相同的重复jar包,这就算作冲突!依赖冲突避免出现重复依赖,并且终止依赖传递!

maven自动解决依赖冲突问题能力,会按照自己的原则,进行重复依赖选择。

解决依赖冲突(如何选择重复依赖)方式:

  1. 自动选择原则

    • 短路优先原则(第一原则)

      A--->B--->C--->D--->E--->X(version 0.0.1)

      A--->F--->X(version 0.0.2)

      则A依赖于X(version 0.0.2)。

    • 依赖路径长度相同情况下,则"先声明优先"(第二原则)

      A--->E--->X(version 0.0.1)

      A--->F--->X(version 0.0.2)

      在<depencies></depencies>中,先声明的,路径相同,会优先选择!

  2. 手动排除

    xml 复制代码
    <dependency>
      <groupId>com.atguigu.maven</groupId>
      <artifactId>pro01-maven-java</artifactId>
      <version>1.0-SNAPSHOT</version>
      <scope>compile</scope>
      <!-- 使用excludes标签配置依赖的排除  -->
      <exclusions>
        <!-- 在exclude标签中配置一个具体的排除 -->
        <exclusion>
          <!-- 指定要排除的依赖的坐标(不需要写version) -->
          <groupId>commons-logging</groupId>
          <artifactId>commons-logging</artifactId>
        </exclusion>
      </exclusions>
    </dependency>

三、Maven工程继承和聚合关系

1. 继承关系

继承概念

在 Maven 的项目中,让一个项目从另一个项目中继承配置信息的机制。可以让我们在多个项目中共享同一配置信息,简化项目的管理和维护工作。

继承作用

继承作用在父工程中统一管理项目中的依赖信息。

它的背景是:

  • 对一个比较大型的项目进行了模块拆分。
  • 一个 project 下面,创建了很多个 module。
  • 每一个 module 都需要配置自己的依赖信息。

继承语法

父工程

xml 复制代码
		  <groupId>com.atguigu.maven</groupId>
          <artifactId>pro03-maven-parent</artifactId>
          <version>1.0-SNAPSHOT</version>
          <!-- 当前工程作为父工程,它要去管理子工程,所以打包方式必须是 pom -->
          <packaging>pom</packaging>

子工程

xml 复制代码
<!-- 使用parent标签指定当前工程的父工程 -->
<parent>
  <!-- 父工程的坐标 -->
  <groupId>com.atguigu.maven</groupId>
  <artifactId>pro03-maven-parent</artifactId>
  <version>1.0-SNAPSHOT</version>
</parent>

<!-- 子工程的坐标 -->
<!-- 如果子工程坐标中的groupId和version与父工程一致,那么可以省略 -->
<artifactId>pro04-maven-module</artifactId>

父工程依赖统一管理

父工程声明版本

xml 复制代码
<!-- 使用dependencyManagement标签配置对依赖的管理 -->
<!-- 被管理的依赖并没有真正被引入到工程 -->
<dependencyManagement>
  <dependencies>
    <dependency>
      <groupId>org.springframework</groupId>
      <artifactId>spring-core</artifactId>
      <version>6.0.10</version>
    </dependency>
    <dependency>
      <groupId>org.springframework</groupId>
      <artifactId>spring-beans</artifactId>
      <version>6.0.10</version>
    </dependency>
    <dependency>
      <groupId>org.springframework</groupId>
      <artifactId>spring-context</artifactId>
      <version>6.0.10</version>
    </dependency>
    <dependency>
      <groupId>org.springframework</groupId>
      <artifactId>spring-expression</artifactId>
      <version>6.0.10</version>
    </dependency>
    <dependency>
      <groupId>org.springframework</groupId>
      <artifactId>spring-aop</artifactId>
      <version>6.0.10</version>
    </dependency>
  </dependencies>
</dependencyManagement>

子工程引用版本

xml 复制代码
<!-- 子工程引用父工程中的依赖信息时,可以把版本号去掉。  -->
<!-- 把版本号去掉就表示子工程中这个依赖的版本由父工程决定。 -->
<!-- 具体来说是由父工程的dependencyManagement来决定。 -->
<dependencies>
  <dependency>
    <groupId>org.springframework</groupId>
    <artifactId>spring-core</artifactId>
  </dependency>
  <dependency>
    <groupId>org.springframework</groupId>
    <artifactId>spring-beans</artifactId>
  </dependency>
  <dependency>
    <groupId>org.springframework</groupId>
    <artifactId>spring-context</artifactId>
  </dependency>
  <dependency>
    <groupId>org.springframework</groupId>
    <artifactId>spring-expression</artifactId>
  </dependency>
  <dependency>
    <groupId>org.springframework</groupId>
    <artifactId>spring-aop</artifactId>
  </dependency>
</dependencies>

2. 聚合关系

聚合概念:

Maven 聚合是指将多个项目组织到一个父级项目中,以便一起构建和管理的机制。可以帮助我们更好地管理一组相关的子项目,同时简化它们的构建和部署过程。

聚合作用

  1. 管理多个子项目:通过聚合,可以将多个子项目组织在一起,方便管理和维护。
  2. 构建和发布一组相关的项目:通过聚合,可以在一个命令中构建和发布多个相关的项目,简化了部署和维护工作。
  3. 优化构建顺序:通过聚合,可以对多个项目进行顺序控制,避免出现构建依赖混乱导致构建失败的情况。
  4. 统一管理依赖项:通过聚合,可以在父项目中管理公共依赖项和插件,避免重复定义。
  5. 聚合语法父项目中包含的子项目列表。
xml 复制代码
<project>
  <groupId>com.example</groupId>
  <artifactId>parent-project</artifactId>
  <packaging>pom</packaging>
  <version>1.0.0</version>
  <modules>
    <module>child-project1</module>
    <module>child-project2</module>
  </modules>
</project>
  1. 聚合演示通过触发父工程构建命令、引发所有子模块构建!产生反应堆!
相关推荐
乔大将军2 小时前
项目准备(flask+pyhon+MachineLearning)- 1
后端·python·flask
码熔burning2 小时前
(十 九)趣学设计模式 之 中介者模式!
java·设计模式·中介者模式
_TokaiTeio2 小时前
微服务100道面试题
java·微服务
eqwaak02 小时前
基于Spring Cloud Alibaba的电商系统微服务化实战:从零到生产级部署
java·分布式·微服务·云原生·架构
m0_672656542 小时前
【Rabbitmq篇】高级特性----TTL,死信队列,延迟队列
java·rabbitmq·java-rabbitmq
胡图蛋.2 小时前
Spring 中哪些情况下,不能解决循环依赖问题?
java·后端·spring
24k小善2 小时前
Flink Oceanbase Connector详解
java·大数据·flink
大白的编程日记.2 小时前
【Linux学习笔记】Linux基本指令及其发展史分析
linux·笔记·学习
ChinaRainbowSea2 小时前
8. Nginx 配合 + Keepalived 搭建高可用集群
java·运维·服务器·后端·nginx
猫头鹰~2 小时前
Ubuntu20.04安装Redis
java·数据库·redis