【问题标题】:Feign with Hystrix Fallback throwing bean error on startup使用 Hystrix Fallback 假装在启动时抛出 bean 错误
【发布时间】:2019-08-11 06:55:44
【问题描述】:

我正在研究来自here 的关于 Feign 和 Hystrix 的示例。如果没有 Feign 后备属性,一切正常。但是当我添加 fallback 属性并创建实现 feign clients 接口的 fallback 类时,我收到以下错误

 Description:

Field customerClient in com.feign.demo.controllers.CustomerController required a single bean, but 2 were found:
    - customerClientFallback: defined in file [../ApplicationFeign/target/classes/com/feign/demo/clients/fallback/CustomerClientFallback.class]
    - com.feign.demo.clients.CustomerClient: defined in null


Action:

Consider marking one of the beans as @Primary, updating the consumer to accept multiple beans, or using @Qualifier to identify the bean that should be consumed

下面是我的 Feign 客户端界面:

@FeignClient(name = "CUSTOMERSERVICE", fallback = CustomerClientFallback.class, primary = false)
@RequestMapping(value = "customer")
public interface CustomerClient {

    @RequestMapping(method = RequestMethod.GET, value = "/getAllCustomers")
    List<Customer> getAllCustomers();

    @RequestMapping(method = RequestMethod.PATCH, value = "/{customerId}", consumes = "application/json")
    Customer update(@PathVariable("customerId") long customerId, @RequestBody Customer customer);

    @RequestMapping(method = RequestMethod.GET, value = "/{customerId}")
    Customer getCustomerById(@PathVariable("customerId") long customerId);

    @RequestMapping(method = RequestMethod.POST, value = "/", consumes = "application/json")
    Customer saveCustomer(@RequestBody Customer customer);

}

CustomerClientFallback 实现:

@Component
public class CustomerClientFallback implements CustomerClient {

    @Override
    public List<Customer> getAllCustomers() {

        return new ArrayList<Customer>();
    }

    @Override
    public Customer update(long customerId, Customer customer) {
        // TODO Auto-generated method stub
        return null;
    }

    @Override
    public Customer getCustomerById(long customerId) {
        // TODO Auto-generated method stub
        return null;
    }

    @Override
    public Customer saveCustomer(Customer customer) {
        // TODO Auto-generated method stub
        return null;
    }

}

应用类:

@SpringBootApplication
@EnableFeignClients
@EnableDiscoveryClient
@EnableHystrix
@EnableHystrixDashboard
public class ApplicationFeignApplication {

    public static void main(String[] args) {
        SpringApplication.run(ApplicationFeignApplication.class, args);

    }

}

春季云版:

Greenwich.SR1




<dependency>
            <groupId>org.springframework.boot</groupId>
            <artifactId>spring-boot-starter-actuator</artifactId>
        </dependency>
        <dependency>
            <groupId>org.springframework.cloud</groupId>
            <artifactId>spring-cloud-starter-netflix-hystrix</artifactId>
        </dependency>
        <dependency>
            <groupId>org.springframework.cloud</groupId>
            <artifactId>spring-cloud-starter-netflix-hystrix-dashboard</artifactId>
        </dependency>

Bellow 是一种修改,但效果不佳。

@RestController
public class CustomerController {

    @Autowired
    private CustomerClient customerClient;

    @Autowired
    public CustomerController(@Qualifier("customerClientFallback") CustomerClient customerClient) {
        this.customerClient = customerClient;
    }

    @RequestMapping(path = "/getAllCustomers", method = RequestMethod.GET)
    public ResponseEntity<Object> getAllCustomers() {
        List<Customer> customers = customerClient.getAllCustomers();
        return new ResponseEntity<>(customers, HttpStatus.OK);

    }

    @RequestMapping(path = "/{customerId}", method = RequestMethod.GET)
    public ResponseEntity<Object> get(@PathVariable() long customerId) {
        try {
            Customer c = customerClient.getCustomerById(customerId);
            if (c != null) {
                return new ResponseEntity<>(c, HttpStatus.OK);
            } else {
                return ResponseEntity.status(HttpStatus.NOT_FOUND).body("Customer Not Found");
            }
        } catch (Exception e) {
            e.printStackTrace();
            return ResponseEntity.status(HttpStatus.INTERNAL_SERVER_ERROR).body(e.getMessage());
        }
    }

    @RequestMapping(path = "/{customerId}", method = RequestMethod.PATCH)
    public ResponseEntity<Object> UpdateCustomer(@PathVariable() Long customerId, @RequestBody Customer customer) {
        Customer c;
        try {
            c = customerClient.update(customerId, customer);
            if (c != null) {
                return new ResponseEntity<>(c, HttpStatus.OK);
            } else {
                return ResponseEntity.status(HttpStatus.NOT_FOUND).body("Customer Not Found");
            }
        } catch (Exception e) {
            e.printStackTrace();
            return ResponseEntity.status(HttpStatus.INTERNAL_SERVER_ERROR).body(e.getMessage());
        }
    }

    @RequestMapping(path = "", method = RequestMethod.POST)
    public ResponseEntity<Object> saveCustomer(@RequestBody Customer customer) {
        Customer c;
        try {
            c = customerClient.saveCustomer(customer);
            return new ResponseEntity<>(c, HttpStatus.OK);
        } catch (Exception e) {
            e.printStackTrace();
            return ResponseEntity.status(HttpStatus.INTERNAL_SERVER_ERROR).body(e.getMessage());
        }
    }
}

【问题讨论】:

  • 可以加CustomerController.java类吗?

标签: spring-cloud spring-cloud-netflix hystrix spring-cloud-feign


【解决方案1】:

在你的控制器类中使用CustomerClient.java feign 客户端似乎有问题。

请确保您添加的是qualifier

@Autowired
private CustomerClient customerClient;

@Autowired
public CustomerController(@Qualifier("customerClientFallback") CustomerClient customerClient ) {
    this.customerClient= customerClient;
}

现在应该可以了。

我建议您查看FallBackFactory 以获得更多关于假装异常处理的功能,

【讨论】:

  • 同样的错误。 com.feign.demo.controllers.CustomerController 中的字段 customerClient 需要一个 bean,但找到了 2 个: - customerClientFallback:在文件 [../microservices_ws/ApplicationFeign/target/classes/com/feign/demo/clients/fallback/ 中定义CustomerClientFallback.class] - com.feign.demo.clients.CustomerClient:在 null 中定义
  • 请在您的问题中附上您的CustomerController.java 课程
  • 添加在问题底部
【解决方案2】:

这是 Spring Cloud 中的已知错误,请参阅: https://github.com/spring-cloud/spring-cloud-netflix/issues/2677

【讨论】:

  • 我没有看到任何解决方案,我已经将 enable hystrix 属性添加到启用。仍然没有解决方法。
【解决方案3】:

从字段中移除自动装配注解,您已经在构造函数中注入了依赖项。

private CustomerClient customerClient;

@Autowired
public CustomerController(@Qualifier("customerClientFallback") CustomerClient customerClient) {
    this.customerClient = customerClient;
}

使用构造函数依赖注入而不是字段注入也更安全 - 通过字段注入,您允许任何人在无效状态下创建您的类的实例。在构造函数中明确指定了依赖项,并且更容易测试您的代码(模拟依赖项并在构造函数中使用它们)

此外,当您使用 @RequestMapping 注释接口或类时,即使您有 @FeignClient 注释,Spring 也会注册一个处理程序 - 并且由于您有此接口的实现,您应该将其删除以避免任何模糊映射问题。

像这样

@FeignClient(name = "CUSTOMERSERVICE", fallback = CustomerClientFallback.class, primary = false)
public interface CustomerClient {

    @RequestMapping(method = RequestMethod.GET, value = "/getAllCustomers")
    List<Customer> getAllCustomers();

    @RequestMapping(method = RequestMethod.PATCH, value = "/{customerId}", consumes = "application/json")
    Customer update(@PathVariable("customerId") long customerId, @RequestBody Customer customer);

    @RequestMapping(method = RequestMethod.GET, value = "/{customerId}")
    Customer getCustomerById(@PathVariable("customerId") long customerId);

    @RequestMapping(method = RequestMethod.POST, value = "/", consumes = "application/json")
    Customer saveCustomer(@RequestBody Customer customer);

}

【讨论】:

    【解决方案4】:

    错误似乎是由于在类/接口级别提供的@RequestMapping

    你的情况是因为@RequestMapping(value = "customer") in CustomerClient.java

    【讨论】:

      猜你喜欢
      • 2016-12-23
      • 2016-06-15
      • 2016-07-17
      • 2018-12-29
      • 1970-01-01
      • 1970-01-01
      • 2013-01-19
      • 2023-03-21
      • 1970-01-01
      相关资源
      最近更新 更多