【问题标题】:Migration netflix feign in Springboot 1.x to openfeign in Springboot 2.x将 Spring Boot 1.x 中的 netflix feign 迁移到 Spring Boot 2.x 中的 openfeign
【发布时间】:2018-10-17 08:23:40
【问题描述】:

我尝试将 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$1.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)

【问题讨论】:

    标签: java spring spring-boot netflix-feign spring-cloud-feign


    【解决方案1】:

    这是Feign documentation的解决方案:

    如果我们要创建多个具有相同名称或 url 的 feign 客户端 这样他们就会指向同一个服务器,但每个服务器都有不同的 自定义配置然后我们必须使用contextId属性 @FeignClient 为了避免这些配置的名称冲突 豆子。

    @FeignClient(contextId = "fooClient", name = "stores", configuration = FooConfiguration.class)
    public interface FooClient {
        //..
    }
    
    @FeignClient(contextId = "barClient", name = "stores", configuration = BarConfiguration.class)
    public interface BarClient {
        //..
    }
    

    https://github.com/spring-cloud/spring-cloud-openfeign/pull/90/commits/82fa5181fdd2e23e7414521f468ecea88e17d157

    【讨论】:

      【解决方案2】:

      您可能有多个具有相同名称属性的@FeignClient 定义。

      【讨论】:

        【解决方案3】:

        如果您不小心有多个使用 @EnableFeignClients 注释的 @Configuration 类,也会发生这种情况

        【讨论】:

        • 这为我解决了问题。但我仍然希望在不同的模块中有两个单独的配置。
        【解决方案4】:

        我找到了解决方案,但它是解决方法。请看@Alessandro Dionisi response

        application.yml:

        spring:
          main:
            allow-bean-definition-overriding: true
        

        【讨论】:

        • 是的,这是一种解决方法,但不是解决方案,谢谢@AlessandroDionisi
        • 这绝对是一种解决方法,您应该考虑重命名您的 feignclients 或使用不同的 url 相互分隔。
        • 这种解决方法会导致您遇到更复杂的问题,因为它掩盖了您的 bean 的问题
        • @Lu55,请参阅 Alessandro Dionisi 回复
        【解决方案5】:

        mvn clean package 为我修复了这个错误

        【讨论】:

          【解决方案6】:

          考虑重命名其中一个 bean 或通过设置 spring.main.allow-bean-definition-overriding=true 来启用覆盖

          【讨论】:

          • 您复制/粘贴我的答案,但这不是解决方案,而是解决方法
          猜你喜欢
          • 1970-01-01
          • 1970-01-01
          • 2019-02-01
          • 1970-01-01
          • 1970-01-01
          • 2018-10-15
          • 1970-01-01
          • 2019-07-12
          相关资源
          最近更新 更多