This is my fourth day of the August Challenge

This series of code address: github.com/HashZhang/s…

Let’s review one of the most important principles of Maven dependencies: the shortest path principle. This is something that we’re going to use a lot later on.

As an example, suppose we use spring-boot-parent as the parent:

<parent> <groupId>org.springframework.boot</groupId> <artifactId>spring-boot-starter-parent</artifactId> The < version > 2.0.9 < / version > < / parent >Copy the code

We want to use ElasticSearch as the search engine and add a dependency to the project

< the dependency > < groupId > org. Elasticsearch < / groupId > < artifactId > elasticsearch < / artifactId > < version > 7.10.2 < / version > </dependency>Copy the code

Write good code, a run, report class no exceptions:

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 moreCopy the code

MVN DEPENDENCY :tree MVN Dependency :tree

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.1Copy the code

If you specify a dependency for ElasticSearch, it’s the root POM of your project. Shouldn’t this dependency prevail?

Careful analysis, the original SpringBoot DependencyManagement, org. Elasticsearch: elasticsearch has been included (the following excerpt) :

<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>Copy the code

Spring-boot actually takes into account the possibility that users may want to change versions, so it puts the version in . Properties also has the shortest path rule, so you can change the version by adding the same key to the properties in your project root POM:

< the properties > < elasticsearch. Version > 7.10.2 < / elasticsearch version > < / properties >Copy the code

All Properties that can be replaced in this way are listed in the official Spring-boot documentation. See the official documentation appendix: Version Properties

You can also use the shortest path principle of dependencyManagement by adding the dependencyManagement to the root POM of your project:

<dependencyManagement> <dependencies> <dependency> <groupId>org.elasticsearch</groupId> <artifactId> elasticSearch </artifactId> </version> 7.10.2</version> </dependency> </dependencies> </dependencyManagement>Copy the code

Finally, keep the following principles in mind to know which version your project’s dependencies are:

Maven dependencies can be broken down into the following parts:

  1. Direct dependencies are the dependencies in the Dependencies section of the project
  2. Indirect dependencies are those contained in the dependencies section of the project named Dependencies
  3. Dependency management is the dependency management in this project
  4. Parent’s direct dependency
  5. Parent’s indirect dependency
  6. Parent dependency management
  7. Direct dependence on BOM (usually none)
  8. Indirect dependence on BOM (usually none)
  9. Bom dependency management

Dependency can be understood this way:

  1. First, insert parent’s direct, indirect, and dependency management into the project before the project’s direct, indirect, and dependency management
  2. For direct dependencies, if there are versions, they are placed in the DependencyMap in turn. If there is no version, the version is found from the dependency management and put into the DependencyMap. Key is the groupId + artifactId of the dependency, and value is version. The value of the subsequent key will be replaced with the value of the previous one
  3. For each dependency, load its own pom file as per 1,2, but if the project dependency management has a dependency version in step 1, use the dependency version of the project dependency management. Generate a TransitiveDependencyMap that contains all indirect dependencies.
  4. All the transitivedependencyMaps of indirect dependencies are placed in the project’s DependencyMap for keys not found in the project’s DependencyMap
  5. If there are indirect dependencies in the TransitiveDependencyMap then perform 3 and 4 recursively.

Since the project DependencyMap is placed first and then the TransitiveDependencyMap is recursed, this explains the shortest path principle for Maven dependencies.

Bom has the same effect as Parent, except that it has dependencyManagement instead of dependencies

As shown in the figure below, we abstracted the following dependencies:

  1. Parent for all projects: Manages Spring Cloud dependencies with a version of Spring Boot as parent and includes some common dependencies, as well as unit test dependencies. If we want to change the Spring Boot or Spring Cloud version in the future, do so here. In addition, all project compilation configurations are specified.
  2. Spring Framework Common: All public dependencies that use Spring or Spring Boot. This is usually added when you write a starter or toolkit that doesn’t require features of the Spring Cloud.
  3. Spring Cloud Common: Added a dependency on Spring Framework Common. Our microservices are divided into synchronous microservice projects mainly based on Spring-WebMVC and asynchronous microservice projects mainly based on Spring-WebFlux. Some common dependencies and code are put in this project.
  4. Spring Cloud WebMVC: Added dependencies for Spring Cloud Common. Core dependencies that need to be added for a Spring-WebMVc-based synchronous microservice project.
  5. Spring Cloud WebFlux: Added a dependency on Spring Cloud Common. Core dependencies that need to be added for a Spring-WebFlux-based asynchronous microservice project.

The main dependencies we use in microservice projects are:

  1. For pure toolkits that use only Spring and Spring Boot features, add dependencies on Spring Framework Common.
  2. Add a spring Cloud WebMVC dependency for spring-WebMVc-based synchronous microservice projects.
  3. For asynchronous spring-WebFlux-based microservice projects, add spring Cloud WebFlux dependencies.

In this section, we reviewed and deeply understood the Maven dependency shortest path principle, and then gave the structure of our project framework, mainly providing three kinds of external dependencies: Only dependencies on Spring and Spring Boot features, dependencies on synchronous spring-WebMVC-based microservices, and dependencies on asynchronous Spring-WebFlux-based microservices are used. The poM files for these project modules will be examined in detail in the next section.

Wechat search “my programming cat” to follow the public account, every day, easy to improve technology, win a variety of offers