在用spring boot开发微服务应用时,会使用到 Spring Cloud或者Spring Cloud Alibaba组件,或者都用。这里的组件指的就是jar包。
在确定spring boot的版本后,如何确定Spring Cloud或者Spring Cloud Alibaba的版本,pom文件该如何配置?
比如我用的spring boot 版本是2.1.8(比较老),那我想使用Spring Cloud的open fein、gateway以及Spring Cloud Alibaba的nacos等组件,pom文件该如何配置依赖关系?
1. 比如我的项目叫tinymall-product,刚建好之后,长这个样子,可以看到默认它的父项目是spring-boot-starter-parent:
<parent>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-parent</artifactId>
<version>2.1.8.RELEASE</version>
<relativePath />
</parent>
<artifactId>tinymall-product</artifactId>
<version>0.0.1-SNAPSHOT</version>
<name>tinymall-product</name>
<description>商品服务</description>
2. 然后加入openfeign和nacos依赖,注意没有标注版本哦
<dependency>
<groupId>org.springframework.cloud</groupId>
<artifactId>spring-cloud-starter-openfeign</artifactId>
</dependency>
<dependency>
<groupId>com.alibaba.cloud</groupId>
<artifactId>spring-cloud-starter-alibaba-nacos-discovery</artifactId>
</dependency>
3. 下边重点来了,那该如何确定使用版本呢?既然我们在依赖里边没有指定版本,那本springboot项目的父项目spring-boot-starter-parent会不会包含他们的版本呢?我们知道当新建一个springboot项目后,IDE默认会把spring-boot-starter-parent做为父项目。之所以这样,很重要一个原因就是这个父项目(spring-boot-starter-parent)的父项目(spring-boot-dependencies)指定了很多依赖的版本号,比如:
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-dependencies</artifactId>
<version>2.1.8.RELEASE</version>
<packaging>pom</packaging>
<name>Spring Boot Dependencies</name>
<description>Spring Boot Dependencies</description>
<dependencyManagement>
<dependencies>
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot</artifactId>
<version>2.1.8.RELEASE</version>
</dependency>
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-test</artifactId>
<version>2.1.8.RELEASE</version>
</dependency>
...
...
因为springboot 和 spring cloud以及spring clould alibaba是三个独立的组件集合,从包管理的角度看,们互相之间没有包含关系。也就是说他们自己都会有一个依赖版本控制项目(项目名字是xxxxx-dependencies.), 专门用于指定组件集合内各模块的版本。比如springboot是上文提到的spring-boot-dependencies, spring cloud是spring-cloud-dependencies,如下所示:
<artifactId>spring-cloud-dependencies</artifactId>
<version>Greenwich.SR3</version>
<name>spring-cloud-dependencies</name>
<description>Spring Cloud Dependencies</description>
<packaging>pom</packaging>
<properties>
<main.basedir>${basedir}/../..</main.basedir>
<spring-cloud-aws.version>2.1.3.RELEASE</spring-cloud-aws.version>
<spring-cloud-bus.version>2.1.3.RELEASE</spring-cloud-bus.version>
<spring-cloud-cloudfoundry.version>2.1.3.RELEASE</spring-cloud-cloudfoundry.version>
<spring-cloud-commons.version>2.1.3.RELEASE</spring-cloud-commons.version>
<spring-cloud-config.version>2.1.4.RELEASE</spring-cloud-config.version>
<spring-cloud-consul.version>2.1.3.RELEASE</spring-cloud-consul.version>
<spring-cloud-contract.version>2.1.3.RELEASE</spring-cloud-contract.version>
<spring-cloud-function.version>2.0.2.RELEASE</spring-cloud-function.version>
<spring-cloud-gateway.version>2.1.3.RELEASE</spring-cloud-gateway.version>
<spring-cloud-gcp.version>1.1.3.RELEASE</spring-cloud-gcp.version>
<spring-cloud-kubernetes.version>1.0.3.RELEASE</spring-cloud-kubernetes.version>
<spring-cloud-netflix.version>2.1.3.RELEASE</spring-cloud-netflix.version>
<spring-cloud-openfeign.version>2.1.3.RELEASE</spring-cloud-openfeign.version>
<spring-cloud-security.version>2.1.4.RELEASE</spring-cloud-security.version>
<spring-cloud-sleuth.version>2.1.3.RELEASE</spring-cloud-sleuth.version>
<spring-cloud-stream.version>Fishtown.SR4</spring-cloud-stream.version>
<spring-cloud-task.version>2.1.3.RELEASE</spring-cloud-task.version>
<spring-cloud-vault.version>2.1.3.RELEASE</spring-cloud-vault.version>
<spring-cloud-zookeeper.version>2.1.3.RELEASE</spring-cloud-zookeeper.version>
</properties>
<dependencyManagement>
<dependencies>
<!-- bom dependencies at the bottom so they can be overridden above -->
<dependency>
<groupId>org.springframework.cloud</groupId>
<artifactId>spring-cloud-commons-dependencies</artifactId>
<version>${spring-cloud-commons.version}</version>
<type>pom</type>
<scope>import</scope>
...
...
<dependency>
<groupId>org.springframework.cloud</groupId>
<artifactId>spring-cloud-openfeign-dependencies</artifactId> <<<<<
<version>${spring-cloud-openfeign.version}</version>
<type>pom</type>
<scope>import</scope>
</dependency>
因为我这个示例项目要用到spring clould的openfeign组件,而这个spring-cloud-dependencies的dependencyManagement里没有直接包含spring-cloud-starter-openfeign的版本,但是他依赖了另外一个依赖文件spring-cloud-openfeign-dependencies,而该依赖文件最终定义了spring-cloud-starter-openfeign的版本:
<artifactId>spring-cloud-openfeign-dependencies</artifactId>
<version>2.1.3.RELEASE</version>
<packaging>pom</packaging>
<name>spring-cloud-openfeign-dependencies</name>
<description>Spring Cloud OpenFeign Dependencies</description>
<dependencyManagement>
<dependencies>
<dependency>
<dependency>
<groupId>org.springframework.cloud</groupId>
<artifactId>spring-cloud-starter-openfeign</artifactId>
<version>${project.version}</version>
</dependency>
结论:
所以为了使用spring cloud里边的组件,我们可以通过在我们的项目的pom文件的<dependencyManagement>里边,集中指定我们使用的spring-cloud的版本,比如这里使用的是Greenwich.SR3
<artifactId>tinymall-product</artifactId>
<version>0.0.1-SNAPSHOT</version>
<name>tinymall-product</name>
<description>商品服务</description>
<properties>
<java.version>1.8</java.version>
<spring-cloud.version>Greenwich.SR3</spring-cloud.version>
</properties>
<dependencyManagement>
<dependencies>
<dependency>
<groupId>org.springframework.cloud</groupId>
<artifactId>spring-cloud-dependencies</artifactId>
<version>${spring-cloud.version}</version>
<type>pom</type>
<scope>import</scope>
</dependency>
</dependencies>
</dependencyManagement>
具体哪一个spring boot版本跟哪一个spring clould版本配套,可以查看官方文档:
https://spring.io/projects/spring-cloud
同样,如果我们的项目需要使用Spring Cloud Alibaba里边的组件,比如服务注册和配置管理组件Nacos,那我们也需要在我么自己的项目的pom文件的<dependencyManagement>中再加上一个Spring Cloud Alibaba的dependency 版本管理 项目文件,最终pom文件的<dependencyManagement>部分内容就是下边这样:
<dependencyManagement>
<!-- introduce spring cloud alibaba dependencies version management and use it
for spring cloud alibaba components -->
<dependencies>
<dependency>
<groupId>com.alibaba.cloud</groupId>
<artifactId>spring-cloud-alibaba-dependencies</artifactId>
<version>2.1.0.RELEASE</version>
<type>pom</type>
<scope>import</scope>
</dependency>
<!-- introduce spring cloud dependencies version management and use it
for spring cloud components -->
<dependency>
<groupId>org.springframework.cloud</groupId>
<artifactId>spring-cloud-dependencies</artifactId>
<version>${spring-cloud.version}</version>
<type>pom</type>
<scope>import</scope>
</dependency>
</dependencies>
</dependencyManagement>
总结:
为了能够正确在spring boot项目配置各组件依赖关系,需要做到以下几点:
1. 需要对Spring Boot, Spring Cloud或者Spring Cloud Alibaba三者之间的关系搞清楚,他们都代表了一些组件的集合(简单来说就是一组jar包)
2. 从maven的包管理角度看,他们彼此之间不是互相包含的关系,是彼此独立的
3. 需要理解maven如何利用<dependencyManagement>以及dependencies类型的项目来实现集中版本控制