乐趣区

关于spring:SpringCloud升级之路20200x版4maven依赖回顾以及项目框架结构

本系列代码地址:https://github.com/HashZhang/…

咱们先来回顾下 maven 依赖中一个重要准则:最短门路准则。这在之后咱们的应用中会常常用到。

举一个例子,假如咱们以 spring-boot-parent 作为 parent:

<parent>
    <groupId>org.springframework.boot</groupId>
    <artifactId>spring-boot-starter-parent</artifactId>
    <version>2.0.9</version>
</parent>

咱们想用想用 elasticsearch 作为搜索引擎,在我的项目中增加了依赖

<dependency>
    <groupId>org.elasticsearch</groupId>
    <artifactId>elasticsearch</artifactId>
    <version>7.10.2</version>
</dependency>

写好代码,一跑,报类不存在异样:

 java.lang.NoClassDefFoundError: org/elasticsearch/common/xcontent/DeprecationHandler
    at com.lv.springboot.datasource.ClientUTis.main(ClientUTis.java:13)
Caused by: java.lang.ClassNotFoundException: org.elasticsearch.common.xcontent.DeprecationHandler
    at java.net.URLClassLoader.findClass(URLClassLoader.java:381)
    at java.lang.ClassLoader.loadClass(ClassLoader.java:424)
    at sun.misc.Launcher$AppClassLoader.loadClass(Launcher.java:331)
    at java.lang.ClassLoader.loadClass(ClassLoader.java:357)
    ... 1 more

看下依赖 mvn dependency:tree,发现依赖的elasticsearch 版本是:

org.elasticsearch.client:elasticsearch-rest-high-level-client:7.0.1
|--org.elasticsearch:elasticsearch:5.6.16
|--org.elasticsearch.client:elasticsearch-rest-client:7.0.1
|--org.elasticsearch.plugin:parent-join-client:7.0.1
|--org.elasticsearch.plugin:aggs-matrix-stats-client:7.0.1
|--org.elasticsearch.plugin:rank-eval-client:7.0.1
|--org.elasticsearch.plugin:lang-mustache-client:7.0.1

可能读者会感觉很奇怪,明明指定了 elasticsearch 的依赖了啊,而且是我的项目的根 pom,依赖不是最短门路准则么?不应该以这个依赖为准么?

仔细分析,原来 SpringBoot 的 DependencyManagement 中,org.elasticsearch:elasticsearch曾经被蕴含了(以下为节选):

<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-dependencies</artifactId>
<version>2.0.9.RELEASE</version>

<properties>
<elasticsearch.version>5.6.16</elasticsearch.version>
</properties>

<dependencyManagement>
    <dependencies>
        <dependency>
            <groupId>org.elasticsearch</groupId>
            <artifactId>elasticsearch</artifactId>
            <version>${elasticsearch.version}</version>
        </dependency>
    </dependencies>
</dependencyManagement>

spring-boot 其实曾经思考到用户可能要换版本了,所以将版本放入了 <properties/>,properties 也具备最短门路准则,所以能够通过在你的我的项目根 pom 中的 properties 减少雷同 key 批改版本:

<properties>
    <elasticsearch.version>7.10.2</elasticsearch.version>
</properties>

所有能够这么替换的属性,spring-boot 官网文档曾经列出了,参考官网文档附录:Version Properties

也能够通过 dependencyManagement 的最短门路准则,通过在你的我的项目根 pom 中的减少想批改依赖的 dependencyManagement 即可:

<dependencyManagement>
    <dependencies>
        <dependency>
            <groupId>org.elasticsearch</groupId>
            <artifactId>elasticsearch</artifactId>
            <version>7.10.2</version>
        </dependency>
    </dependencies>
</dependencyManagement>

最初,能够记住上面的准则,就晓得我的项目的依赖到底是哪个版本啦:

Maven 依赖能够分为如下几局部:

  1. 间接依赖,就是本我的项目 dependencies 局部的依赖
  2. 间接依赖,就是本我的项目 dependencies 局部的依赖所蕴含的依赖
  3. 依赖治理,就是本我的项目 dependency management 外面的依赖
  4. parent 的间接依赖
  5. parent 的间接依赖
  6. parent 的依赖治理
  7. bom 的间接依赖(个别没有)
  8. bom 的间接依赖(个别没有)
  9. bom 的依赖治理

能够这么了解依赖:

  1. 首先,将 parent 的间接依赖,间接依赖,还有依赖治理,插入本我的项目,放入本我的项目的间接依赖,间接依赖还有依赖治理之前
  2. 对于间接依赖,如果有 version,那么就顺次放入 DependencyMap 中。如果没有 version,则从依赖治理中查出来 version,之后放入 DependencyMap 中。key 为依赖的 groupId + artifactId,value 为 version,后放入的会把之前放入的雷同 key 的 value 替换
  3. 对于每个依赖,各自依照 1,2 加载本人的 pom 文件,然而如果第一步中的本我的项目 dependency management 中有依赖的版本,应用本我的项目 dependency management 的依赖版本,生成 TransitiveDependencyMap,这外面就蕴含了所有的间接依赖。
  4. 所有间接依赖的 TransitiveDependencyMap,对于我的项目的 DependencyMap 外面没有的 key,顺次放入我的项目的 DependencyMap
  5. 如果 TransitiveDependencyMap 外面还有间接依赖,那么递归执行 3,4。

因为是先放入本我的项目的 DependencyMap,再去递归 TransitiveDependencyMap,这就解释了 maven 依赖的最短门路准则。

Bom 的成果根本和 Parent 一样,只是个别限度中,Bom 只有 dependencyManagement 没有 dependencies

如下图所示,咱们会形象出如下几个依赖:

  1. 所有我的项目的 parent:以某版本 Spring Boot 作为 parent,治理 Spring Cloud 依赖,并且包含一些公共依赖,还有单元测试依赖。如果当前咱们想批改 Spring Boot 或者 Spring Cloud 版本,就在这里批改。并且,指定了所有我的项目编译配置。
  2. Spring Framework Common:所有应用了 Spring 或者 Spring Boot 的公共依赖,个别咱们编写 starter,或者编写一些工具包,不须要 Spring Cloud 的个性,就会增加这个依赖。
  3. Spring Cloud Common:增加了 Spring Framework Common 的依赖。咱们的微服务分为次要基于 spring-webmvc 的同步微服务项目以及次要基于 spring-webflux 的异步微服务项目,其中有一些公共的依赖和代码,就放在了这个我的项目中。
  4. Spring Cloud WebMVC:增加了 Spring Cloud Common 的依赖。基于 spring-webmvc 的同步微服务项目须要增加的外围依赖。
  5. Spring Cloud WebFlux:增加了 Spring Cloud Common 的依赖。基于 spring-webflux 的异步微服务项目须要增加的外围依赖。

咱们在微服务项目中次要应用的依赖为:

  1. 对于纯工具包,只应用了 Spring 与 Spring Boot 的个性的,增加 Spring Framework Common 的依赖。
  2. 对于基于 spring-webmvc 的同步微服务项目,增加 Spring Cloud WebMVC 的依赖。
  3. 对于基于 spring-webflux 的异步微服务项目,增加 Spring Cloud WebFlux 的依赖。

本大节咱们回顾了并深刻了解了 maven 依赖最短门路准则,而后给出了咱们我的项目框架的构造,次要对外提供了三种依赖:只应用了 Spring 与 Spring Boot 的个性的依赖,对于基于 spring-webmvc 的同步微服务项目的依赖以及对于基于 spring-webflux 的异步微服务项目的依赖。下一节咱们将对这些我的项目模块的 pom 文件进行详细分析。

微信搜寻“我的编程喵”关注公众号,每日一刷,轻松晋升技术,斩获各种 offer

退出移动版