首页 > 技术文章 > 在SpringCloud中使用Feign的两种方式

wugang 2021-03-03 23:51 原文

在SpringCloud中通常使用OpenFeign来封装微服务接口,有如下两种方式:

一、RequestLine注解

1.准备config

@Configuration
public class FeginConfig {
    @Bean
    public Contract feignConfiguration() {
        return new feign.Contract.Default();
    }
}

2.申明接口

@FeignClient(name = "EMPLOYEE", configuration = FeginConfig.class)
public interface EmployeeService1 {
    @RequestLine("POST /employee/add")
    @Headers({"Content-Type: application/json", "Accept: application/json"})
    CommonResult add(TblEmployee employee);

    @RequestLine("POST /employee/addBatch")
    @Headers({"Content-Type: application/json", "Accept: application/json"})
    CommonResult addBatch(List<TblEmployee> employee);
}

二、RequestMapping/PostMapping/GetMapping注解

此种方式比较简单,直接定义接口

@FeignClient("EMPLOYEE")
public interface EmployeeService {
    //@PostMapping(value = "/employee/add")
    @RequestMapping(value="/employee/add",consumes = "application/json",method = RequestMethod.POST)
    CommonResult add(TblEmployee employee);

    @PostMapping(value = "/employee/addBatch")
        //@RequestMapping(value="/employee/addBatch",consumes = "application/json",method = RequestMethod.POST)
    CommonResult addBatch(List<TblEmployee> employee);
}

三、使用

@SpringBootApplication
@EnableEurekaClient
@EnableDiscoveryClient  

@EnableFeignClients
@RestController
public class WebApp {
    public static void main(String[] args) {
        SpringApplication.run(WebApp.class, args);
    }

    @Autowired(required = false)
    private Contract cc;

    @Autowired(required = false)
    private EmployeeService employeeService;

    @Autowired(required = false)
    private EmployeeService1 employeeService1;

    @PostMapping("add")
    public CommonResult add(@RequestBody TblEmployee employee) {
        return employeeService.add(employee);
    }

    @PostMapping("addBatch")
    public CommonResult addBatch(@RequestBody List<TblEmployee> employees) {
        return employeeService.addBatch(employees);
    }

    @GetMapping("/test")
    public String test() {
        Class<? extends Contract> aClass = cc.getClass();
        return aClass == null ? "" : aClass.getName();
    }
}

常见问题

1.在使用RequestMapping/PostMapping/GetMapping时,如果注入了Contract,且实例为new feign.Contract.Default()。就会出现如下异常:

org.springframework.beans.factory.UnsatisfiedDependencyException: Error creating bean with name 'webApp': Unsatisfied dependency expressed through field 'employeeService'; nested exception is org.springframework.beans.factory.BeanCreationException: Error creating bean with name 'com.laowu.service.EmployeeService': FactoryBean threw exception on object creation; nested exception is java.lang.IllegalStateException: Method EmployeeService#add(TblEmployee) not annotated with HTTP method type (ex. GET, POST)
Warnings:
- Class EmployeeService has annotations [FeignClient] that are not used by contract Default
- Method add has an annotation RequestMapping that is not used by contract Default

有两种解决办法:

1.不注入Contract

//@Configuration
public class FeginConfig {
    //@Bean
    public Contract feignConfiguration() {
       return new feign.Contract.Default();
    }
}

2.注入SpringMvcContract。

@Configuration
public class FeginConfig {
    @Bean
    public Contract feignConfiguration() {
        return new SpringMvcContract();
    }
}

推荐阅读