Я работаю над примером из здесь о Feign и Hystrix. Без резервного свойства Feign все работает нормально. Но когда я добавляю резервное свойство и создаю резервный класс, реализующий интерфейс фиктивных клиентов, я получаю следующую ошибку.
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());
}
}
}





Кажется, есть проблема из-за использования CustomerClient.java feign client в вашем классе контроллера.
Пожалуйста, убедитесь, что вы добавляете qualifier
@Autowired
private CustomerClient customerClient;
@Autowired
public CustomerController(@Qualifier("customerClientFallback") CustomerClient customerClient ) {
this.customerClient= customerClient;
}
Это должно работать сейчас.
Я предлагаю вам заглянуть в ОсеньНазадФабрика, чтобы получить больше возможностей для имитации обработки исключений,
Та же ошибка. Поле customerClient в com.feign.demo.controllers.CustomerController требовало одного bean-компонента, но было найдено 2: — customerClientFallback: определено в файле [../microservices_ws/ApplicationFeign/target/classes/com/feign/demo/clients/ fallback/CustomerClientFallback.class] – com.feign.demo.clients.CustomerClient: определено значение null
Пожалуйста, прикрепите свой CustomerController.java класс к вашему вопросу
Добавлено внизу вопроса
Это известная ошибка в Spring Cloud, см.: https://github.com/spring-cloud/spring-cloud-netflix/issues/2677
Я не вижу там решения, я уже добавил свойство enable hystrix во включенное. Все еще нет обходного пути.
Удалите аннотацию autowired из поля, вы уже вводите зависимость в конструкторе.
private CustomerClient customerClient;
@Autowired
public CustomerController(@Qualifier("customerClientFallback") CustomerClient customerClient) {
this.customerClient = customerClient;
}
Также безопаснее использовать внедрение зависимостей конструктора вместо внедрения поля — с внедрением поля вы позволяете любому создать экземпляр вашего класса в недопустимом состоянии. В конструкторе четко указаны зависимости, а также легче тестировать свой код (издеваться над зависимостями и использовать их в конструкторе).
Кроме того, когда вы аннотируете интерфейс или класс с помощью @RequestMapping, Spring зарегистрирует обработчик, даже если у вас есть аннотация @FeignClient, и, поскольку у вас есть реализация этого интерфейса, вы должны удалить ее, чтобы избежать проблем с неоднозначным сопоставлением.
Вот так
@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);
}
Ошибка, кажется, из-за @RequestMapping, предоставленного на уровне класса/интерфейса.
В вашем случае из-за @RequestMapping(value = "customer") в CustomerClient.java
Не могли бы вы добавить
CustomerController.javaкласс?