首页 > 其他分享 >Maven项目依赖管理

Maven项目依赖管理

时间:2022-11-14 21:13:06浏览次数:81  
标签:ssm 依赖 03 项目 jar pojo Maven maven

Maven项目依赖管理

我们现在已经能把项目拆分成一个个独立的模块,当在其他项目中想要使用独立出来的这些模块,只需要在其pom.xml使用<dependency>标签来进行jar包的引入即可。

<dependency>其实就是依赖,关于依赖管理里面都涉及哪些内容,如下:

  • 依赖传递
  • 可选依赖
  • 排除依赖

我们先来理解一下什么是依赖:

依赖指当前项目运行所需的jar,一个项目可以设置多个依赖。

格式为:

<!--设置当前项目所依赖的所有jar-->
<dependencies>
    <!--设置具体的依赖-->
    <dependency>
        <!--依赖所属群组id-->
        <groupId>org.springframework</groupId>
        <!--依赖所属项目id-->
        <artifactId>spring-webmvc</artifactId>
        <!--依赖版本号-->
        <version>5.2.15.RELEASE</version>
    </dependency>
</dependencies>

1. 依赖传递与冲突问题

回到我们刚才的项目案例中,打开Maven的面板,你会发现:

在项目所依赖的这些jar包中,有一个比较大的区别就是有的依赖前面有箭头>,有的依赖前面没有。

那么这个箭头所代表的含义是什么?

打开前面的箭头,你会发现这个jar包下面还包含有其他的jar

你会发现maven_03_ssm_pojomaven_03_ssm_daomaven_03_ssm_service的依赖多次被加载到Dependencies中,那么maven_03_ssm_controller中的maven_03_ssm_pojomaven_03_ssm_daomaven_03_ssm_service能不能使用呢?

要想验证非常简单,只需要把maven_03_ssm_controller项目中pom.xml关于maven_03_ssm_pojomaven_03_ssm_dao的依赖注释或删除掉

Dependencies中移除自己所添加maven_03_ssm_pojomaven_03_ssm_dao依赖后,打开UserController的类,你会发现User类依然存在,可以被正常使用

这个特性其实就是我们要讲解的依赖传递

依赖是具有传递性的:

说明:A代表自己的项目;BCDEFG代表的是项目所依赖的jar包;D1D2E1E2代表是相同jar包的不同版本

(1) A依赖了BCBC有分别依赖了其他jar包,所以在A项目中就可以使用上面所有jar包,这就是所说的依赖传递

(2) 依赖传递有直接依赖和间接依赖

  • 相对于A来说,A直接依赖BC,间接依赖了D1E1GFD2E2
  • 相对于B来说,B直接依赖了D1E1,间接依赖了G
  • 直接依赖和间接依赖是一个相对的概念

(3) 因为有依赖传递的存在,就会导致jar包在依赖的过程中出现冲突问题,具体什么是冲突?Maven是如何解决冲突的?

这里所说的依赖冲突是指项目依赖的某一个jar包,有多个不同的版本,因而造成类包版本冲突。

情况一:在maven_02_ssmpom.xml中添加两个不同版本的Junit依赖:

<dependencies>
    <dependency>
      <groupId>junit</groupId>
      <artifactId>junit</artifactId>
      <version>4.13.2</version>
      <scope>test</scope>
    </dependency>
    <dependency>
      <groupId>junit</groupId>
      <artifactId>junit</artifactId>
      <version>4.12</version>
      <scope>test</scope>
    </dependency>
</dependencies>

通过对比,会发现一个结论

  • 特殊优先:当同级配置了相同资源的不同版本,后配置的覆盖先配置的。

情况二:路径优先:当依赖中出现相同的资源时,层级越深,优先级越低,层级越浅,优先级越高

  • A通过B间接依赖到E1
  • A通过C间接依赖到E2
  • A就会间接依赖到E1E2Maven会按照层级来选择,E1是2度,E2是3度,所以最终会选择E1

情况三:声明优先:当资源在相同层级被依赖时,配置顺序靠前的覆盖配置顺序靠后的

  • A通过B间接依赖到D1
  • A通过C间接依赖到D2
  • D1D2都是两度,这个时候就不能按照层级来选择,需要按照声明来,谁先声明用谁,也就是说BC之前声明,这个时候使用的是D1,反之则为D2

但是对应上面这些结果,不需要刻意去记它。因为不管Maven怎么选,最终的结果都会在MavenDependencies面板中展示出来,展示的是哪个版本,也就是说它选择的就是哪个版本,如:

如果想更全面的查看Maven中各个坐标的依赖关系,可以点击Maven面板中的show Dependencies

在这个视图中就能很明显的展示出jar包之间的相互依赖关系。

2. 可选依赖和排除依赖

依赖传递介绍完以后,我们来思考一个问题,

  • maven_02_ssm 依赖了 maven_03_ssm_controller
  • maven_03_ssm_controller 依赖了maven_03_ssm_servicemaven_03_ssm_pojo
  • maven_03_ssm_service 依赖了maven_03_ssm_daomaven_03_ssm_pojo
  • maven_03_ssm_dao依赖了 maven_03_ssm_pojo
  • 因为现在有依赖传递,所以maven_02_ssm能够使用到maven_03_ssm_pojo的内容
  • 如果说现在不想让maven_02_ssm依赖到maven_03_ssm_pojo,有哪些解决方案?

说明:在真实使用的过程中,maven_02_ssm中是需要用到maven_03_ssm_pojo的,我们这里只是用这个例子描述我们的需求。因为有时候,maven_03_ssm_dao出于某些因素的考虑,就是不想让别人使用自己所依赖的maven_03_ssm_pojo

方案一:可选依赖

  • 可选依赖指对外隐藏当前所依赖的资源---不透明

maven_03_ssm_daopom.xml,在引入maven_03_ssm_pojo的时候,添加optional

        <dependency>
            <groupId>com.dcxuexi</groupId>
            <artifactId>maven_03_ssm_pojo</artifactId>
            <version>1.0-SNAPSHOT</version>
            <!--可选依赖是隐藏当前工程所依赖的资源,隐藏后对应资源将不具有依赖传递-->
            <optional>true</optional>
        </dependency>

此时UserServiceI就已经报错了,说明由于maven_03_ssm_daomaven_03_ssm_pojo设置成可选依赖,导致maven_03_ssm_service无法引用到maven_03_ssm_pojo中的内容,导致User类找不到。

方案二:排除依赖

  • 排除依赖指主动断开依赖的资源,被排除的资源无需指定版本---不需要

前面我们已经通过可选依赖实现了阻断maven_03_ssm_pojo的依赖传递,对于排除依赖,则指的是已经有依赖的事实,也就是说maven_03_ssm_service项目中已经通过依赖传递用到了maven_03_ssm_pojo,此时我们需要做的是将其进行排除,所以接下来需要修改maven_02_ssmpom.xml

        <dependency>
            <groupId>com.dcxuexi</groupId>
            <artifactId>maven_03_ssm_dao</artifactId>
            <version>1.0-SNAPSHOT</version>
            <!--排除依赖是隐藏当前资源对应的依赖关系-->
            <exclusions>
                <exclusion>
                    <groupId>com.dcxuexi</groupId>
                    <artifactId>maven_03_ssm_pojo</artifactId>
                </exclusion>
            </exclusions>
        </dependency>

这样操作后,UserService中的User类一样也会报错。

当然exclusions标签带s说明我们是可以依次排除多个依赖到的jar包,比如maven_03_ssm_dao中有依赖mysql-connector-javamybatis,我们也可以一并将其排除。

        <dependency>
            <groupId>com.dcxuexi</groupId>
            <artifactId>maven_03_ssm_dao</artifactId>
            <version>1.0-SNAPSHOT</version>
            <!--排除依赖是隐藏当前资源对应的依赖关系-->
            <exclusions>
                <exclusion>
                    <groupId>com.dcxuexi</groupId>
                    <artifactId>maven_03_ssm_pojo</artifactId>
                </exclusion>
                <exclusion>
                    <groupId>org.mybatis</groupId>
                    <artifactId>mybatis</artifactId>
                </exclusion>
                <exclusion>
                    <groupId>mysql</groupId>
                    <artifactId>mysql-connector-java</artifactId>
                </exclusion>
            </exclusions>
        </dependency>

介绍我这两种方式后,简单来梳理下,就是

  • A依赖BB依赖CC通过依赖传递会被A使用到,现在要想办法让A不去依赖C
  • 可选依赖是在B上设置<optional>A不知道有C的存在,
  • 排除依赖是在A上设置<exclusions>A知道有C的存在,主动将其排除掉。

项目代码

标签:ssm,依赖,03,项目,jar,pojo,Maven,maven
From: https://www.cnblogs.com/dcbut/p/16890383.html

相关文章