Притворяться с ошибкой броска bean-компонента Hystrix Fallback при запуске - PullRequest
0 голосов
/ 20 марта 2019

Я работаю над примером из здесь о Feign и Hystrix.Без резервного свойства Feign все работает хорошо.Но когда я добавляю свойство 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

Ниже представлен мой интерфейс клиентской симуляции:

@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);

    }

}

Версия Spring Cloud:

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>

Сильфон - это модификация, но она также не работает.

@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());
        }
    }
}

Ответы [ 3 ]

0 голосов
/ 22 марта 2019

Это известная ошибка в Spring Cloud, смотрите: https://github.com/spring-cloud/spring-cloud-netflix/issues/2677

0 голосов
/ 31 марта 2019

Удалите автопроводную аннотацию из поля, вы уже внедряете зависимость в конструкторе.

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);

}
0 голосов
/ 21 марта 2019

Кажется, есть проблема из-за использования CustomerClient.java feign клиента в вашем классе контроллера.

Пожалуйста, убедитесь, что вы добавляете qualifier

@Autowired
private CustomerClient customerClient;

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

Это должно работать сейчас.

Я предлагаю вам взглянуть на FallBackFactory , чтобы получить больше возможностей при обработке искусственных исключений,

...