本系列代码地址: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 依赖能够分为如下几局部:
- 间接依赖,就是本我的项目 dependencies 局部的依赖
- 间接依赖,就是本我的项目 dependencies 局部的依赖所蕴含的依赖
- 依赖治理,就是本我的项目 dependency management 外面的依赖
- parent 的间接依赖
- parent 的间接依赖
- parent 的依赖治理
- bom 的间接依赖(个别没有)
- bom 的间接依赖(个别没有)
- bom 的依赖治理
能够这么了解依赖:
- 首先,将 parent 的间接依赖,间接依赖,还有依赖治理,插入本我的项目,放入本我的项目的间接依赖,间接依赖还有依赖治理之前
- 对于间接依赖,如果有 version,那么就顺次放入 DependencyMap 中。如果没有 version,则从依赖治理中查出来 version,之后放入 DependencyMap 中。key 为依赖的 groupId + artifactId,value 为 version,后放入的会把之前放入的雷同 key 的 value 替换
- 对于每个依赖,各自依照 1,2 加载本人的 pom 文件,然而如果第一步中的本我的项目 dependency management 中有依赖的版本,应用本我的项目 dependency management 的依赖版本,生成 TransitiveDependencyMap,这外面就蕴含了所有的间接依赖。
- 所有间接依赖的 TransitiveDependencyMap,对于我的项目的 DependencyMap 外面没有的 key,顺次放入我的项目的 DependencyMap
- 如果 TransitiveDependencyMap 外面还有间接依赖,那么递归执行 3,4。
因为是先放入本我的项目的 DependencyMap,再去递归 TransitiveDependencyMap,这就解释了 maven 依赖的最短门路准则。
Bom 的成果根本和 Parent 一样,只是个别限度中,Bom 只有 dependencyManagement 没有 dependencies
如下图所示,咱们会形象出如下几个依赖:
- 所有我的项目的 parent:以某版本 Spring Boot 作为 parent,治理 Spring Cloud 依赖,并且包含一些公共依赖,还有单元测试依赖。如果当前咱们想批改 Spring Boot 或者 Spring Cloud 版本,就在这里批改。并且,指定了所有我的项目编译配置。
- Spring Framework Common:所有应用了 Spring 或者 Spring Boot 的公共依赖,个别咱们编写 starter,或者编写一些工具包,不须要 Spring Cloud 的个性,就会增加这个依赖。
- Spring Cloud Common:增加了 Spring Framework Common 的依赖。咱们的微服务分为次要基于 spring-webmvc 的同步微服务项目以及次要基于 spring-webflux 的异步微服务项目,其中有一些公共的依赖和代码,就放在了这个我的项目中。
- Spring Cloud WebMVC:增加了 Spring Cloud Common 的依赖。基于 spring-webmvc 的同步微服务项目须要增加的外围依赖。
- Spring Cloud WebFlux:增加了 Spring Cloud Common 的依赖。基于 spring-webflux 的异步微服务项目须要增加的外围依赖。
咱们在微服务项目中次要应用的依赖为:
- 对于纯工具包,只应用了 Spring 与 Spring Boot 的个性的,增加 Spring Framework Common 的依赖。
- 对于基于 spring-webmvc 的同步微服务项目,增加 Spring Cloud WebMVC 的依赖。
- 对于基于 spring-webflux 的异步微服务项目,增加 Spring Cloud WebFlux 的依赖。
本大节咱们回顾了并深刻了解了 maven 依赖最短门路准则,而后给出了咱们我的项目框架的构造,次要对外提供了三种依赖:只应用了 Spring 与 Spring Boot 的个性的依赖,对于基于 spring-webmvc 的同步微服务项目的依赖以及对于基于 spring-webflux 的异步微服务项目的依赖。下一节咱们将对这些我的项目模块的 pom 文件进行详细分析。
微信搜寻“我的编程喵”关注公众号,每日一刷,轻松晋升技术,斩获各种 offer: