Spring Cloud中如何优雅的使用Feign调用接口

朱雀 2020-11-08 07:28 1009阅读 0赞
  1. JAVA 项目中接口调用怎么做
  2. Httpclient
  3. Okhttp
  4. Httpurlconnection
  5. RestTemplate
  6. 上面是最常见的几种用法,我们今天要介绍的用法比上面的更简单,方便,它就是 Feign
  7. Feign是一个声明式的REST客户端,它的目的就是让REST调用更加简单。
  8. Feign提供了HTTP请求的模板,通过编写简单的接口和插入注解,就可以定义好HTTP请求的参数、格式、地址等信息。
  9. Feign则会完全代理HTTP请求,我们只需要像调用方法一样调用它就可以完成服务请求及相关处理。
  10. SpringCloudFeign进行了封装,使其支持SpringMVC标准注解和HttpMessageConverters
  11. Feign可以与EurekaRibbon组合使用以支持负载均衡。
  12. SpringCloud中使用Feign
  13. 当我们搭建好注册中心Eureka之后,就是需要将自己的服务注册到Eureka中,然后别的服务可以直接调用。
  14. 首先呢是服务提供方需要注册到Eureka中,这边我们新建一个房产服务fangjia-fsh-house-service
  15. fangjia-fsh-house-service中提供跟房子相关的接口,比如最简单的获取房子的基本信息
  16. /**
  17. * 获取房产信息
  18. * @param houseId 房产编号
  19. * @return
  20. */
  21. @GetMapping("/{houseId}")
  22. public ResponseData hosueInfo(@PathVariable("houseId")Long houseId) {
  23. return ResponseData.ok(houseService.getHouseInfo(houseId));
  24. }
  25. 另外我们起一个项目来消费房产服务的这个接口,房产置换服务fangjia-fsh-substitution-service
  26. /**
  27. * 获取置换信息
  28. * @param sid
  29. * @return
  30. */
  31. @GetMapping("/{sid}")
  32. public ResponseData substitutionInfo(@PathVariable("sid") Long sid) {
  33. return ResponseData.ok(substitutionService.getSubstitutionInfo(sid));
  34. }
  35. substitutionService中需要消费房产服务的获取房产信息接口,一般的做法我们都会通过Httpclient或者最底层的Httpurlconnection来直接调用接口,当然这些都需要自己集成或者封装,在spring里面已经有了一个很好的封装,那就是RestTemplate来调用接口。
  36. 关于RestTemplate的使用可以查看我的这篇文章:http://cxytiandi.com/blog/detail/6157
  37. 可以直接注入对象,然后调用接口,这种方式唯一的弊端就是你需要知道服务提供者的地址,根据指定的地址来进行调用
  38. @Autowired
  39. private RestTemplate restTemplate;
  40. @Override
  41. public SubstitutionDto getSubstitutionInfo(Long sid) {
  42. House house = this.restTemplate.getForObject("http://localhost:8000/hosue/" + id, House.class);
  43. // .......
  44. }
  45. 另一种就是我们今天的主角,简单的调用方式就是使用一个声明式的REST客户端Feign来进行接口调用
  46. 用了Feign之后调用接口只需要定义相同的接口即可实现调用
  47. 使用Feign肯定要引入jar的依赖
  48. <dependency>
  49. <groupId>org.springframework.cloud</groupId>
  50. <artifactId>spring-cloud-starter-feign</artifactId>
  51. </dependency>
  52. 在启动类上加@EnableFeignClients注解,如果你的Feign接口定义跟你的启动类不在一个包名下,还需要制定扫描的包名@EnableFeignClients(basePackages = "com.fangjia.api.client")
  53. 这边建议大家将接口的消费定义,单独抽一个项目出来,后面打成公共的jar,这样无论是哪个项目需要调用接口,引入公共的接口SDK jar即可,不用重新定义一遍了。
  54. **
  55. * 房生活房产服务API调用客户端
  56. *
  57. * @author yinjihuan
  58. * @create 2017-10-27 13:55
  59. **/
  60. @FeignClient(value = "fangjia-fsh-house-service", path = "/house", configuration = FeignConfiguration.class, fallback = HouseRemoteClientHystrix.class)
  61. public interface HouseRemoteClient {
  62. /**
  63. * 获取企业下某用户的有效房产信息
  64. * @param eid 企业编号
  65. * @param uid 用户编号
  66. * @return
  67. */
  68. @GetMapping("/list/{eid}/{uid}")
  69. public HouseListDto hosueList(@PathVariable("eid")Long eid, @PathVariable("uid")String uid);
  70. /**
  71. * 获取房产详细信息
  72. * @param houseId 房产编号
  73. * @return
  74. */
  75. @GetMapping("/{houseId}")
  76. public HouseInfoDto hosueInfo(@PathVariable("houseId")Long houseId);
  77. }
  78. @FeignClient里的value表示你要消费哪个服务的接口,path就是统一的前缀,也就是我们HouseController中类上面的@RequestMapping(“/house”)的地址
  79. @FeignClient里的configuration可以让你自定义配置信息来覆盖Feign的默认配置,
  80. 比如配置日志输出
  81. 日志的输出还需要在配置文件中指定才能生效logging.level.com.fangjia.api.client.fsh.house.HouseRemoteClient=DEBUG
  82. @Configuration
  83. public class FeignConfiguration {
  84. @Bean
  85. Logger.Level feignLoggerLevel() {
  86. return Logger.Level.FULL;
  87. }
  88. }
  89. @FeignClient里的fallback可以让你的接口在熔断处理时,返回默认的值给调用方,这个一般有2种方式:
  90. - 实现Feign的接口,实现所有的默认方法
  91. /**
  92. * 房产服务调用熔断默认返回处理
  93. *
  94. * @author yinjihuan
  95. * @create 2017-10-29 14:30
  96. **/
  97. @Component
  98. public class HouseRemoteClientHystrix implements HouseRemoteClient {
  99. @Override
  100. public HouseListDto hosueList(Long eid, String uid) {
  101. return new HouseListDto();
  102. }
  103. @Override
  104. public HouseInfoDto hosueInfo(Long houseId) {
  105. return new HouseInfoDto();
  106. }
  107. }
  108. 另一种就是@FeignClient里的fallbackFactory,效果是一样的
  109. 使用的话更简单了,和普通的Service的类一样使用,注入进来,然后直接调用方法就相当于调用远程接口了
  110. @Autowired
  111. private HouseRemoteClient houseRemoteClient;
  112. HouseInfoDto houseInfoDto = houseRemoteClient.hosueInfo(1L);
  113. 普通Java项目中如何使用Feign
  114. 通过上面的讲解,在SpringCloud中使用Feign显得那么的自然,因为集成这件事SpringCloud已经帮我们做好了,这是广大开发人员的福音。
  115. 那如果你们没有使用SpringCloud来进行开发,我能用Feign来调用接口马,答案是:当然
  116. 首先你需要看一遍文档,如果还不会用你来找我:https://github.com/OpenFeign/feign
  117. 我们看官方的提个Demo:
  118. 定义了一个GitHub的接口调用类,上面配置了请求方式以及参数,是通过Feign自带的注解方式配置的
  119. 然后通过Feign.builder()构建一个客户端,同时可以设置编码,解码需要用到的类,以及访问的目标地址等等信息,当然也包括日志的设置,输出等等。。
  120. interface GitHub {
  121. @RequestLine("GET /repos/{owner}/{repo}/contributors")
  122. List<Contributor> contributors(@Param("owner") String owner, @Param("repo") String repo);
  123. }
  124. static class Contributor {
  125. String login;
  126. int contributions;
  127. }
  128. public static void main(String... args) {
  129. GitHub github = Feign.builder()
  130. .decoder(new GsonDecoder())
  131. .target(GitHub.class, "https://api.github.com");
  132. // Fetch and print a list of the contributors to this library.
  133. List<Contributor> contributors = github.contributors("OpenFeign", "feign");
  134. for (Contributor contributor : contributors) {
  135. System.out.println(contributor.login + " (" + contributor.contributions + ")");
  136. }
  137. }

发表评论

表情:
评论列表 (有 0 条评论,1009人围观)

还没有评论,来说两句吧...

相关阅读