step1. 导入feign的依赖
<dependency>
<groupId>org.springframework.cloud</groupId>
<artifactId>spring-cloud-starter-feign</artifactId>
</dependency>
step2. 在启动程序添加注解
@SpringBootApplication
@EnableEurekaClient
@EnableFeignClients //feign,http客户端
public class ConsumerMovieFeignApplication {
public static void main(String[] args) {
SpringApplication.run(ConsumerMovieFeignApplication.class, args);
System.out.println("【【【ConsumerMovieFeignApplication启动了】】】");
}
}
step3. 写一个接口
Spring Cloud
应用在启动时,Feign
会扫描标有@FeignClient
注解的接口,生成代理,并注册到Spring
容器中。生成代理时Feign
会为每个接口方法创建一个RequetTemplate
对象,该对象封装了HTTP请求需要的全部信息,请求参数名、请求方法等信息都是在这个过程中确定的,Feign
的模板化就体现在这里。
在本例中,我们将Feign
与Eureka
和Ribbon
组合使用,@FeignClient(name = "provider-user")
意为通知Feign
在调用该接口方法时要向Eureka
中查询名为provider-user
的服务,从而得到服务URL
。
/**
* @Author: yuju
* @Date: 2018/5/11 - 10:56
*/
// @FeignClient用于通知Feign组件对该接口进行代理(不需要编写接口实现),使用者可直接通过@Autowired注入。
@FeignClient(name = "provider-user")
public interface UserFeignClient {
//@RequestMapping表示在调用该方法时需要向/simple/{id}发送GET请求。
@RequestMapping(value = "/simple/{id}",method = RequestMethod.GET)//feign不支持GetMapping
User findById(@PathVariable("id") Long id);//@PathVariable 要设置value
}
坑 ①:如果上文中的@RequestMapping(value = "/simple/{id}",method = RequestMethod.GET)
改为@GetMapping("/simple/{id}")
会报异常Caused by: java.lang.IllegalStateException: Method xxx not annotated with HTTP method type (ex. GET, POST)
坑 ②:如果上文中的User findById(@PathVariable("id") Long id);
写为User findById(@PathVariable Long id)
,会报异常Caused by: java.lang.IllegalStateException: PathVariable annotation was empty on param 0
坑 ③:如果当feign client
接收的参数没有被@RequestParam
注解修饰时,会自动被当做request body
来处理。只要有body
,就会被feign
认为是post
请求,所以整个服务是被当作带有request parameter
和body
的post
请求发送出去的。也就是说,即使指定了method = RequestMethod.GET
,也默认使用post
方法发送请求
step4. 利用feign调用服务
/**
* @Author: yuju
* @Date: 2018/4/28 - 14:11
*/
@RestController
public class MovieController {
@Autowired
private UserFeignClient userFeignClient;
@GetMapping("/movie/{id}")
public User findById(@PathVariable Long id){
return userFeignClient.findById(id);
}
}
step5. 现在你可以愉快的通过movie请求到user了
最后附上provider-user的controller代码:
/**
* @Author: yuju
* @Date: 2018/4/28 - 10:38
*/
@RestController
public class UserController {
@Autowired
private UserRepository userRepository;
@GetMapping("/simple/{id}")
public User findById(@PathVariable Long id){
return userRepository.findOne(id);
}
}
注:为了使文章篇幅不至于太长,只贴了必要的代码、
!!码字辛苦,转载请注明出处!!