使用SpringCloudAlibaba方案进行微服务开发时,虽说SpringCloudAlibaba在SpringCloud的基础上更进了一步,但核心还是SpringCloud,只是采用了几个阿里自己的中间件,也就是说SpringCloudAlibaba也是基于SpringBoot的,并且例如网关等中间件阿里仍然采用的是SpringCloud方案中的Gateway网关,在项目中就又会引入SpringCloud的的组件,所以就涉及到三者版本兼容性的问题。

1、三者关系

  • spring boot:一个为简化spring应用开发而出现的框架,比如spring MVC应用的开发等。
  • spring cloud:一套全家桶的微服务解决框架,理念就是解决我们在微服务架构中遇到的任何问题,包括解决微服务开发中各种问题问题的组件,微服务是一个理念。spring cloud就提供了工具在应用实现这个理念。由于springcloud的组件基于spring boot开发的,所以springcloud是基于springboot。
  • spring cloud alibaba:实现对SpringCloud组件进行扩展

2、版本对应关系


SpringMVC兼容springcloud springcloud版本冲突_spring boot

SpringCloud的版本:

我们对上边图片内容做一些说明。首先是SpringCloud的版本号,最初采用的伦敦地铁站的名称作为版本号,因为SpringCloud包含众多子项目,为了避免与子项目的版本号产生冲突,也为了更好的管理,故而采用了这种版本描述方式。但是最新的版本已经开始使用时间的版本描述方式了。

比如SpringCloud Hoxton.SR3:Hoxton就是版本名称,SR3又是只什么呢?这与官方的版本发布计划有关,其实就是对版本的进一步描述。

SpringMVC兼容springcloud springcloud版本冲突_spring boot_02


SpringBoot和SpringCloudAlibaba:

由于 Spring Boot 1 和 Spring Boot 2 在 Actuator 模块的接口和注解有很大的变更,且 spring-cloud-commons 从 1.x.x 版本升级到 2.0.0 版本也有较大的变更,因此SpringClouAlibaba采取跟 SpringBoot 版本号一致的版本:

  • 1.5.x 版本适用于 Spring Boot 1.5.x
  • 2.0.x 版本适用于 Spring Boot 2.0.x
  • 2.1.x 版本适用于 Spring Boot 2.1.x
  • 2.2.x 版本适用于 Spring Boot 2.2.x
  • 2021.x 版本适用于 Spring Boot 2.4.x

3、在项目中如何实现依赖项目的版本管理

因为都是Maven项目,所以首先要明白Maven是如何实现依赖项目版本管理的

3.1 Maven的<dependencyManagement>标签

<dependencyManagement标签是一个和<dependencies>标签同级的一个标签,作用就是描述依赖的版本,<dependencyManagement>标签内部又会包含一个<dependencies>标签,<dependencies>标签又会包含依赖<dependencie><dependencyManagement>标签管理版本依赖,但不会真正的引入依赖。例如:

<dependencyManagement>
        <dependencies>
            <dependency>
	            <groupId>mysql</groupId>
	            <artifactId>mysql-connector-java</artifactId>
	            <version>8.0.25</version>
            </dependency>
        </dependencies>
</dependencyManagement>

在真正引入时我就可以这样:

<dependencies>
            <dependency>
	            <groupId>mysql</groupId>
	            <artifactId>mysql-connector-java</artifactId>
	            <!-- 不加版本号 -->
            </dependency>
        </dependencies>

有小伙伴看到就说了,你这不多此一举,版本号直接写依赖下面不就行了。NoNoNo,我们知道Maven的pom是可以继承的,微服务项目都会有众多模块,有些模块就会有相同的依赖,而这个依赖其他模块就不需要,所以这些依赖不能放在公共模块中,那怎么让各模块依赖的版本号一致呢?就是<dependencyManagement>,在父项目中加入依赖的版本管理,子项目就可以全部不用加版本号了,因为子项目会继承它,并且修改版本的时候只需要在父项目修改即可。

3.2 SpringCloud的版本管理

SpringCloud项目中包含了众多的组件,组件也都会有自己的版本,那我们引入多个SpringCloud的组件时(例如:gateway,feign),怎么保证这些个组件都是属于同一个SpringCloud的版本呢?

答案就是spring-cloud-dependencies项目,在这个项目的中就写了大量的</dependencyManagement>,管理着spring-cloud中各个组件的版本,并且这个项目的版本号是和SpringCloud的版本号一致的,比如Hoxton.SR3,每一个版本的spring-cloud-dependencies项目,管理的组件的版本都是不同的,所以通过spring-cloud-dependencies项目的版本就可以确定组件的版本。

所以我们在项目中就要把它继承过来,继承到当前项目中,并且给他指定版本号,这样我们就不用自己写版本号了。

所以又出现了一个问题,pom是单继承的,父项目只能有一个,SpringCloud的个组件版本有spring-cloud-dependencies项目管理,那SpringCloudAlibaba的依赖项目版本也有spring-cloud-alibaba-dependencies项目管理,如果我们项同时继承两个pom怎么办呢?

Maven采用的是单继承的方式,所以使用<parent>标签是不行的,因为不能又两个<parent>标签。

这时候老朋友<dependencyManagement>标签又登场了。比如想要继承spring-cloud-dependenciesspring-cloud-alibaba-dependencies项目,就可以这么写:

<dependencyManagement>
        <dependencies>
            <dependency>
                <groupId>com.alibaba.cloud</groupId>
                <artifactId>spring-cloud-alibaba-dependencies</artifactId>
                <version>2.2.1.RELEASE</version>
                <type>pom</type>
                <scope>import</scope>
            </dependency>

            <dependency>
                <groupId>org.springframework.cloud</groupId>
                <artifactId>spring-cloud-dependencies</artifactId>
                <version>Hoxton.SR3</version>
                <type>pom</type>
                <scope>import</scope>
            </dependency>
        </dependencies>
    </dependencyManagement>

这里解释一下<type><scop>

  • type表示项目类型,这里是涉及到Maven的打包方式,<packaging>标签,我们常用的是jar包(默认就是jar)和war包,就是让maven执行打包命令时,将项目压缩为指定格式的包,除了这两种也可以是<packaging>pom</packaging>,表示打包成pom文件,执行maven的packaging命令结果就是一个pom文件。
  • scop是核心,表示把引入当前项目,scope为import只能在dependencyManagement中使用,且type为pom类型。

4、版本管理实现

综上,要使SpringBoot,SpringCloud,SpringCloudAlibaba版本一致对用,只需要在父项目中加入如下的项,只是要注意这里写的SpringBoot的版本和项目中使用的SpringBoot(SpringBoot项目pom的parent标签)的版本要一致:

<dependencyManagement>
        <dependencies>
            <dependency>
                <groupId>org.springframework.boot</groupId>
                <artifactId>spring-boot-dependencies</artifactId>
                <version>2.2.5.RELEASE</version>
                <type>pom</type>
                <scope>import</scope>
            </dependency>

            <dependency>
                <groupId>com.alibaba.cloud</groupId>
                <artifactId>spring-cloud-alibaba-dependencies</artifactId>
                <version>2.2.1.RELEASE</version>
                <type>pom</type>
                <scope>import</scope>
            </dependency>

            <dependency>
                <groupId>org.springframework.cloud</groupId>
                <artifactId>spring-cloud-dependencies</artifactId>
                <version>Hoxton.SR3</version>
                <type>pom</type>
                <scope>import</scope>
            </dependency>
        </dependencies>
    </dependencyManagement>

有的小伙伴说了,我这没有父项目啊,只有一个聚合项目。其实任意模块都可以引入上述代码来实现版本的管理。

比你你要在一个SpringBoot项目中做SpringCloud、SpringCloudAlibaba和SpringBoot的版本的管理,只需要写如下项:

<dependencyManagement>
        <dependencies>
            <dependency>
                <groupId>com.alibaba.cloud</groupId>
                <artifactId>spring-cloud-alibaba-dependencies</artifactId>
                <version>2.2.1.RELEASE</version>
                <type>pom</type>
                <scope>import</scope>
            </dependency>

            <dependency>
                <groupId>org.springframework.cloud</groupId>
                <artifactId>spring-cloud-dependencies</artifactId>
                <version>Hoxton.SR3</version>
                <type>pom</type>
                <scope>import</scope>
            </dependency>
        </dependencies>
    </dependencyManagement>

因为你的项目是SpringBoot项目,该项目的pom已经继承了spring-boot-starter-parent项目的pom,而spring-boot-starter-parent又继承了spring-boot-dependencies,所以SpringBoot的版本在parent标签中指定就行了。


5、总结:用一个实例

<?xml version="1.0" encoding="UTF-8"?>
<project xmlns="http://maven.apache.org/POM/4.0.0" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
         xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 https://maven.apache.org/xsd/maven-4.0.0.xsd">
    <modelVersion>4.0.0</modelVersion>
    <parent>
        <groupId>org.springframework.boot</groupId>
        <artifactId>spring-boot-starter-parent</artifactId>
        <version>2.2.5.RELEASE</version>
        <relativePath/> <!-- lookup parent from repository -->
    </parent>
    <groupId>com.atguigu.gulimall</groupId>
    <artifactId>gulimall-gateway</artifactId>
    <version>0.0.1-SNAPSHOT</version>
    <name>gulimall-gateway</name>
    <description>API网关</description>
    <properties>
        <java.version>1.8</java.version>
        <spring-cloud.version>Hoxton.SR3</spring-cloud.version>
    </properties>
    <dependencies>
        <dependency>
            <groupId>com.atguigu</groupId>
            <artifactId>gulimall-common</artifactId>
            <version>0.0.1-SNAPSHOT</version>
            <exclusions>
                <exclusion>
                    <groupId>org.springframework.boot</groupId>
                    <artifactId>spring-boot-starter-web</artifactId>
                </exclusion>
            </exclusions>
        </dependency>
        <dependency>
            <groupId>org.springframework.cloud</groupId>
            <artifactId>spring-cloud-starter-gateway</artifactId>
        </dependency>
    </dependencies>
    <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>
    <build>
        <plugins>
            <plugin>
                <groupId>org.springframework.boot</groupId>
                <artifactId>spring-boot-maven-plugin</artifactId>
            </plugin>
        </plugins>
    </build>
</project>

实例描述:

  • 这是一个网关模块,继承了spring-boot-starter-parent,所以这是一个SpringBoot项目,在parent标签中指定了使用的SpringBoot的版本为2.2.5.RELEASE。
  • 网关组件使用的是SpringCloud的gateway,所以需要用spring-cloud-dependencies指定SpringCloud的版本为Hoxton.SR3。
  • 项目使用nacos作为注册中心和配置中心,所以在基础模块gulimall-common(该模块引入了它)中用spring-cloud-alibaba-dependencies指定了SpringCloudAlibaba的版本为2.2.1.RELEASE。

至此关于maven中进行项目依赖的版本管理就说完了,如有不足,评论里讨论!