最近在实践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
下,而Finchley.M9
版本下的spring-cloud-starter-openfeign:2.0.0.M2的pom依赖文件中导入的是spring-cloud-netflix-core
而非spring-cloud-openfeign-core
,需要我们在pom文件中添加对应依赖管理使spring-cloud-starter-openfeign版本更新到2.0.0.RC1
,如下图
<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>
1. 创建项目
为了方便讲解分析,这里使用idea创建一个新的SpringBoot+Spring Cloud的Feign项目,一切设置保持默认
项目依赖仅勾选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,查看import信息,这个时候@EnableFeignClients注解的全限定名是org.springframework.cloud.netflix.feign.EnableFeignClients
(重要,后面会提到)
试一下启动,意料之中地报错了,错误是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>
如上,与项目原本的pom相比,就只是在dependencyManagement(声明依赖,并不实现引入)下多了个org.springframework.cloud: spring-cloud-openfeign:2.0.0.RC1
的dependency版本管理.将其引入,即在pom文件中增加如下内容
<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>
发现@EnableFeignClients
没有提示错误了,这时候再来看看项目依赖树
对比一下上面M2版本的依赖树,可以很明显地看到与Feign相关的依赖包的变化是org.springframework.cloud:spring-cloud-netflix-core
换成了org.springframework.cloud:spring-cloud-openfeign-core
直接看一下import信息,发现注解的类名为org.springframework.cloud.openfeign.EnableFeignClients
,与上面看到的做对比,就可以发现@EnableFeignClients
注解由org.springframework.cloud.netflix.feign.EnableFeignClients
换为org.springframework.cloud.openfeign.EnableFeignClients
即在M2版本中@EnableFeignClients的类已经换了,但对应的spring-cloud-starter-openfeign下的依赖却没有更新,所以就找不到对应的类了
知道原因,那我们再来看看org.springframework.cloud:spring-cloud-openfeign-core
这个包的内容
对比一下上面org.springframework.cloud:spring-cloud-netflix-core的内容,就会发现两者几乎一样,这也验证了我们的想法
由此,我们可以得出结论:
Spring Cloud对Feign的支持由org.springframework.cloud:spring-cloud-netflix-core
移到org.springframework.cloud:spring-cloud-openfeign-core
下,而Finchley.M9
版本下的spring-cloud-starter-openfeign:2.0.0.M2的pom依赖文件中导入的是spring-cloud-netflix-core
而非spring-cloud-openfeign-core
,需要我们在pom文件中添加对应依赖管理使spring-cloud-starter-openfeign版本更新到2.0.0.RC1
3. 官方项目日志
最后,再来看看官方项目日志(可以直接去github上面看):
呃,2.0.0.M2和2.0.0.RC1都被回滚了…,现在用的还是2.0.0.BUILD-SNAPSHOT,不过现在(2018年4月25日)官方教程给的current版本是2.0.0.RC1,而且目前没发现问题(至少不会像2.0.0.M2那么坑),所以先用着应该是可以的