将 Spring Boot 1.x 中的 netflix feign 迁移到 Spring Boot 2.x 中的 openfeign
Migration netflix feign in Springboot 1.x to openfeign in Springboot 2.x
我尝试将 Springboot 1.x.y (Brussels-SR12) 迁移到 2.x.y。我使用 FeignClients
我更改 Maven 配置:
<spring-cloud.version>Finchley.RELEASE</spring-cloud.version>
所以
<groupId>org.springframework.cloud</groupId>
<artifactId>spring-cloud-openfeign</artifactId>
<version>2.0.0.RELEASE</version>
我改全导入:
import org.springframework.cloud.netflix.feign.EnableFeignClients;
import org.springframework.cloud.netflix.feign.FeignClient;
至
import org.springframework.cloud.openfeign.EnableFeignClients;
import org.springframework.cloud.openfeign.FeignClient;
我用的是这个界面:
@FeignClient(value = "COMPANY", fallbackFactory = CompanyClientFallbackFactory.class, configuration = FeignConfiguration.class)
public interface CompanyClient extends CompanyApi {
}
当我 运行 我的 JUnit 测试(使用 spring 上下文)时,我现在有这个错误(不在 Springboot 1.x.y 和旧的 netflix 包中):
The bean 'COMPANY.FeignClientSpecification', defined in null, could not be registered. A bean with that name has already been defined in null and overriding is disabled.
完整跟踪:
java.lang.IllegalStateException: Failed to load ApplicationContext
at org.springframework.test.context.cache.DefaultCacheAwareContextLoaderDelegate.loadContext(DefaultCacheAwareContextLoaderDelegate.java:125)
at org.springframework.test.context.support.DefaultTestContext.getApplicationContext(DefaultTestContext.java:108)
at org.springframework.boot.test.mock.mockito.MockitoTestExecutionListener.postProcessFields(MockitoTestExecutionListener.java:99)
at org.springframework.boot.test.mock.mockito.MockitoTestExecutionListener.injectFields(MockitoTestExecutionListener.java:79)
at org.springframework.boot.test.mock.mockito.MockitoTestExecutionListener.prepareTestInstance(MockitoTestExecutionListener.java:54)
at org.springframework.test.context.TestContextManager.prepareTestInstance(TestContextManager.java:246)
at org.springframework.test.context.junit4.SpringJUnit4ClassRunner.createTest(SpringJUnit4ClassRunner.java:227)
at org.springframework.test.context.junit4.SpringJUnit4ClassRunner.runReflectiveCall(SpringJUnit4ClassRunner.java:289)
...
Caused by: org.springframework.beans.factory.support.BeanDefinitionOverrideException: Invalid bean definition with name 'COMPANY.FeignClientSpecification' defined in null: Cannot register bean definition [Generic bean: class [org.springframework.cloud.openfeign.FeignClientSpecification]; scope=; abstract=false; lazyInit=false; autowireMode=0; dependencyCheck=0; autowireCandidate=true; primary=false; factoryBeanName=null; factoryMethodName=null; initMethodName=null; destroyMethodName=null] for bean 'COMPANY.FeignClientSpecification': There is already [Generic bean: class [org.springframework.cloud.openfeign.FeignClientSpecification]; scope=; abstract=false; lazyInit=false; autowireMode=0; dependencyCheck=0; autowireCandidate=true; primary=false; factoryBeanName=null; factoryMethodName=null; initMethodName=null; destroyMethodName=null] bound.
at org.springframework.beans.factory.support.DefaultListableBeanFactory.registerBeanDefinition(DefaultListableBeanFactory.java:896)
at org.springframework.cloud.openfeign.FeignClientsRegistrar.registerClientConfiguration(FeignClientsRegistrar.java:355)
at org.springframework.cloud.openfeign.FeignClientsRegistrar.registerFeignClients(FeignClientsRegistrar.java:155)
at org.springframework.cloud.openfeign.FeignClientsRegistrar.registerBeanDefinitions(FeignClientsRegistrar.java:83)
我找到了解决方案,但它是解决方法。请参阅
application.yml:
spring:
main:
allow-bean-definition-overriding: true
可能您有多个 @FeignClient
具有相同名称属性的定义。
这是 Feign documentation 的解决方案:
If we want to create multiple feign clients with the same name or url
so that they would point to the same server but each with a different
custom configuration then we have to use contextId
attribute of the
@FeignClient
in order to avoid name collision of these configuration
beans.
@FeignClient(contextId = "fooClient", name = "stores", configuration = FooConfiguration.class)
public interface FooClient {
//..
}
@FeignClient(contextId = "barClient", name = "stores", configuration = BarConfiguration.class)
public interface BarClient {
//..
}
考虑重命名其中一个 bean 或通过设置 spring.main.allow-bean-definition-overriding=true
启用覆盖
如果您不小心将多个@Configuration class 注释为@EnableFeignClients
,也会发生这种情况
mvn clean package 为我修复了这个错误
我尝试将 Springboot 1.x.y (Brussels-SR12) 迁移到 2.x.y。我使用 FeignClients
我更改 Maven 配置:
<spring-cloud.version>Finchley.RELEASE</spring-cloud.version>
所以
<groupId>org.springframework.cloud</groupId>
<artifactId>spring-cloud-openfeign</artifactId>
<version>2.0.0.RELEASE</version>
我改全导入:
import org.springframework.cloud.netflix.feign.EnableFeignClients;
import org.springframework.cloud.netflix.feign.FeignClient;
至
import org.springframework.cloud.openfeign.EnableFeignClients;
import org.springframework.cloud.openfeign.FeignClient;
我用的是这个界面:
@FeignClient(value = "COMPANY", fallbackFactory = CompanyClientFallbackFactory.class, configuration = FeignConfiguration.class)
public interface CompanyClient extends CompanyApi {
}
当我 运行 我的 JUnit 测试(使用 spring 上下文)时,我现在有这个错误(不在 Springboot 1.x.y 和旧的 netflix 包中):
The bean 'COMPANY.FeignClientSpecification', defined in null, could not be registered. A bean with that name has already been defined in null and overriding is disabled.
完整跟踪:
java.lang.IllegalStateException: Failed to load ApplicationContext
at org.springframework.test.context.cache.DefaultCacheAwareContextLoaderDelegate.loadContext(DefaultCacheAwareContextLoaderDelegate.java:125)
at org.springframework.test.context.support.DefaultTestContext.getApplicationContext(DefaultTestContext.java:108)
at org.springframework.boot.test.mock.mockito.MockitoTestExecutionListener.postProcessFields(MockitoTestExecutionListener.java:99)
at org.springframework.boot.test.mock.mockito.MockitoTestExecutionListener.injectFields(MockitoTestExecutionListener.java:79)
at org.springframework.boot.test.mock.mockito.MockitoTestExecutionListener.prepareTestInstance(MockitoTestExecutionListener.java:54)
at org.springframework.test.context.TestContextManager.prepareTestInstance(TestContextManager.java:246)
at org.springframework.test.context.junit4.SpringJUnit4ClassRunner.createTest(SpringJUnit4ClassRunner.java:227)
at org.springframework.test.context.junit4.SpringJUnit4ClassRunner.runReflectiveCall(SpringJUnit4ClassRunner.java:289)
...
Caused by: org.springframework.beans.factory.support.BeanDefinitionOverrideException: Invalid bean definition with name 'COMPANY.FeignClientSpecification' defined in null: Cannot register bean definition [Generic bean: class [org.springframework.cloud.openfeign.FeignClientSpecification]; scope=; abstract=false; lazyInit=false; autowireMode=0; dependencyCheck=0; autowireCandidate=true; primary=false; factoryBeanName=null; factoryMethodName=null; initMethodName=null; destroyMethodName=null] for bean 'COMPANY.FeignClientSpecification': There is already [Generic bean: class [org.springframework.cloud.openfeign.FeignClientSpecification]; scope=; abstract=false; lazyInit=false; autowireMode=0; dependencyCheck=0; autowireCandidate=true; primary=false; factoryBeanName=null; factoryMethodName=null; initMethodName=null; destroyMethodName=null] bound.
at org.springframework.beans.factory.support.DefaultListableBeanFactory.registerBeanDefinition(DefaultListableBeanFactory.java:896)
at org.springframework.cloud.openfeign.FeignClientsRegistrar.registerClientConfiguration(FeignClientsRegistrar.java:355)
at org.springframework.cloud.openfeign.FeignClientsRegistrar.registerFeignClients(FeignClientsRegistrar.java:155)
at org.springframework.cloud.openfeign.FeignClientsRegistrar.registerBeanDefinitions(FeignClientsRegistrar.java:83)
我找到了解决方案,但它是解决方法。请参阅
application.yml:
spring:
main:
allow-bean-definition-overriding: true
可能您有多个 @FeignClient
具有相同名称属性的定义。
这是 Feign documentation 的解决方案:
If we want to create multiple feign clients with the same name or url so that they would point to the same server but each with a different custom configuration then we have to use
contextId
attribute of the@FeignClient
in order to avoid name collision of these configuration beans.@FeignClient(contextId = "fooClient", name = "stores", configuration = FooConfiguration.class) public interface FooClient { //.. } @FeignClient(contextId = "barClient", name = "stores", configuration = BarConfiguration.class) public interface BarClient { //.. }
考虑重命名其中一个 bean 或通过设置 spring.main.allow-bean-definition-overriding=true
启用覆盖如果您不小心将多个@Configuration class 注释为@EnableFeignClients
,也会发生这种情况mvn clean package 为我修复了这个错误