最近在实践Spring Boot 2+Spring Cloud(Finchley.M9),在用到Feign
的时候发现@EnableFeignClients
注解开不了,独立使用Feign是可以的,但就是开启不了Spring对Feign的支持.经过一番摸索终于把问题解决了,在这里分享一下解决方案和思路.解决思路写得较繁琐,可以选择性阅读,结论和解决方案写在前面
0. 结论和解决方案
Spring Cloud对Feign的支持由org.springframework.cloud:spring-cloud-netflix-core
移到org.springframework.cloud:spring-cloud-openfeign-core
下,而org.springframework.cloud:spring-cloud-openfeign-core
默认是没有导入
的,需要我们在pom文件中添加对应依赖
<dependency>
<groupId>org.springframework.cloud</groupId>
<artifactId>spring-cloud-openfeign-core</artifactId>
</dependency>
为了方便讲解,这里使用idea创建一个新的SpringBoot+Spring Cloud的Feign项目,一切设置保持默认
1. 创建项目
项目依赖仅勾选Web和Feign
下面贴出项目初始化的pom文件的依赖
<dependencies>
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-web</artifactId>
</dependency>
<dependency>
<groupId>org.springframework.cloud</groupId>
<artifactId>spring-cloud-starter-openfeign</artifactId>
</dependency>
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-test</artifactId>
<scope>test</scope>
</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>
这个时候可以看到在主程序上用不了@EnableFeignClients
注解
2. @EnableFeignClients的位置
问题很明显就是缺少包了,那就先找找@EnableFeignClients是在哪个包里,利用idea的工具,可以看到该注解是在
<dependency>
<groupId>org.springframework.cloud</groupId>
<artifactId>spring-cloud-netflix-core</artifactId>
<version>1.3.5.RELEASE</version>
</dependency>
将其导入pom,启动,意料之中地报错了,错误是org.springframework.beans.factory.BeanDefinitionStoreException
不过这并不要紧,重要是找到了@EnableFeignClients注解在哪里,现在把刚才pom添加的依赖去掉再来看看项目原本的依赖树
可以看到项目本来就有org.springframework.cloud:spring-cloud-netflix-core:2.0.0.M8
.
那是不是说明2.0.0.M8
中没有@EnableFeignClients注解而1.3.5.RELEASE
有呢?很有可能,笔者特地去找了这两个jar包,解压后比较如下:
很直观地看到,Spring Cloud的spring-cloud-netflix-core版本中少了很多东西,其中就包括Feign文件夹,而我们要的@EnableFeignClients和@FeignClient注解就在这个文件夹下
到这里问题已经很清晰了,高版本的Spring Cloud使用的Feign注解不在原来的位置,也不在spring-cloud-openfeign下,所以自然就找不到了
那新的问题又来了,高版本的Spring Cloud使用的Feign注解在哪里,又该如何导入呢?
这里还是从官方提供的依赖入手,下面是官方提供的OpenFeign Quick Start最新教程,版本基本一样
<dependencyManagement>
<dependencies>
<dependency>
<groupId>org.springframework.cloud</groupId>
<artifactId>spring-cloud-openfeign</artifactId>
<version>2.0.0.RC1</version>
<type>pom</type>
<scope>import</scope>
</dependency>
</dependencies>
</dependencyManagement>
<dependencies>
<dependency>
<groupId>org.springframework.cloud</groupId>
<artifactId>spring-cloud-starter-openfeign</artifactId>
</dependency>
</dependencies><repositories>
<repository>
<id>spring-milestones</id>
<name>Spring Milestones</name>
<url>https://repo.spring.io/libs-milestone</url>
<snapshots>
<enabled>false</enabled>
</snapshots>
</repository>
</repositories>
如上,spring-cloud-starter-openfeign依赖我们本来就添加了,现在,我们去dependencyManagement中找找灵感(dependencyManagement是声明依赖,范围比较广,实际引入依赖是在dependencies里,所以很有可能@EnableFeignClients注解在dependencyManagement声明的依赖里但是没有实际导入)
注意:
dependencyManagement里只是声明依赖,并不实现引入
找到.m2\repository\org\springframework\cloud\spring-cloud-openfeign\2.0.0.M2,里面内容如下:
打开pom文件,发现里面的依赖如下:
<dependencyManagement>
<dependencies>
<dependency>
<groupId>org.springframework.cloud</groupId>
<artifactId>spring-cloud-netflix-dependencies</artifactId>
<version>${spring-cloud-netflix.version}</version>
<type>pom</type>
<scope>import</scope>
</dependency>
<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>
<dependency>
<groupId>org.springframework.cloud</groupId>
<artifactId>spring-cloud-openfeign-dependencies</artifactId>
<version>${project.version}</version>
<type>pom</type>
<scope>import</scope>
</dependency>
<dependency>
<groupId>org.springframework.cloud</groupId>
<artifactId>spring-cloud-test-support</artifactId>
<scope>test</scope>
<version>${spring-cloud-commons.version}</version>
</dependency>
<dependency>
<groupId>com.fasterxml.jackson.dataformat</groupId>
<artifactId>jackson-dataformat-smile</artifactId>
<version>${jackson.version}</version>
</dependency>
</dependencies>
</dependencyManagement>
可以看到这个pom引入了
<dependency>
<groupId>org.springframework.cloud</groupId>
<artifactId>spring-cloud-openfeign-dependencies</artifactId>
<version>${project.version}</version>
<type>pom</type>
<scope>import</scope>
</dependency>
顺藤摸瓜,再在本地maven仓库找到了org.springframework.cloud:spring-cloud-openfeign-dependencies:2.0.0.M2,里面也是一个pom文件,依赖如下:
<dependencyManagement>
<dependencies>
<dependency>
<groupId>org.springframework.cloud</groupId>
<artifactId>spring-cloud-openfeign-core</artifactId>
<version>${project.version}</version>
</dependency>
<dependency>
<groupId>org.springframework.cloud</groupId>
<artifactId>spring-cloud-starter-openfeign</artifactId>
<version>${project.version}</version>
</dependency>
<dependency>
<groupId>io.github.openfeign</groupId>
<artifactId>feign-core</artifactId>
<version>${feign.version}</version>
</dependency>
<dependency>
<groupId>io.github.openfeign</groupId>
<artifactId>feign-slf4j</artifactId>
<version>${feign.version}</version>
</dependency>
<dependency>
<groupId>io.github.openfeign</groupId>
<artifactId>feign-httpclient</artifactId>
<version>${feign.version}</version>
</dependency>
<dependency>
<groupId>io.github.openfeign</groupId>
<artifactId>feign-hystrix</artifactId>
<version>${feign.version}</version>
</dependency>
<dependency>
<groupId>io.github.openfeign</groupId>
<artifactId>feign-java8</artifactId>
<version>${feign.version}</version>
</dependency>
<dependency>
<groupId>io.github.openfeign</groupId>
<artifactId>feign-okhttp</artifactId>
<version>${feign.version}</version>
</dependency>
<dependency>
<groupId>io.github.openfeign</groupId>
<artifactId>feign-gson</artifactId>
<version>${feign.version}</version>
</dependency>
<dependency>
<groupId>io.github.openfeign</groupId>
<artifactId>feign-jackson-jaxb</artifactId>
<version>${feign.version}</version>
</dependency>
<dependency>
<groupId>io.github.openfeign</groupId>
<artifactId>feign-jackson</artifactId>
<version>${feign.version}</version>
</dependency>
<dependency>
<groupId>io.github.openfeign</groupId>
<artifactId>feign-java8</artifactId>
<version>${feign.version}</version>
</dependency>
<dependency>
<groupId>io.github.openfeign</groupId>
<artifactId>feign-jaxb</artifactId>
<version>${feign.version}</version>
</dependency>
<dependency>
<groupId>io.github.openfeign</groupId>
<artifactId>feign-jaxrs</artifactId>
<version>${feign.version}</version>
</dependency>
<dependency>
<groupId>io.github.openfeign</groupId>
<artifactId>feign-ribbon</artifactId>
<version>${feign.version}</version>
</dependency>
<dependency>
<groupId>io.github.openfeign</groupId>
<artifactId>feign-sax</artifactId>
<version>${feign.version}</version>
</dependency>
</dependencies>
</dependencyManagement>
其中最主要的就是前三个依赖org.springframework.cloud下的spring-cloud-openfeign-core
和spring-cloud-starter-openfeign
,还有io.github.openfeign下的feign-core
,观察项目的依赖树,可以发现io.github.openfeign下的feign-core包含在org.springframework.cloud下的spring-cloud-starter-openfeign中,唯独在依赖树中看不到org.springframework.cloud:spring-cloud-openfeign-core
嗯,org.springframework.cloud:spring-cloud-openfeign-core
这个名字似乎暗示了点什么,我好像看到了希望,先把它加到pom中试试再说(这个时候本地maven仓库还没有该jar包,比较难看到内容,所以先放到pom文件里可以让maven下载jar包)
<dependency>
<groupId>org.springframework.cloud</groupId>
<artifactId>spring-cloud-openfeign-core</artifactId>
</dependency>
忽然发现@EnableFeignClients
没有提示错误了,run一下试试,发现也可以了!
很好,我们再回过来看看spring-cloud-openfeign-core
的内容,在本地maven仓库找到它的jar包,解压,如下:
对比一下上面org.springframework.cloud:spring-cloud-netflix-core的内容,就会发现两者几乎一样
由此,我们可以得出结论:
Spring Cloud对Feign的支持由org.springframework.cloud:spring-cloud-netflix-core
移到org.springframework.cloud:spring-cloud-openfeign-core
下,而org.springframework.cloud:spring-cloud-openfeign-core
默认是没有导入
的,需要我们在pom文件中添加对应依赖.
上面也看到了,不仅仅是Spring Cloud对Feign的支持从org.springframework.cloud:spring-cloud-netflix-core
移出,其他很多组件也都没有了,原因应该与Feign类似,如果遇到类似问题可以按照本文思路尝试一下.