之前也用过Feign,不过是在SpringCloud体系内用的,需要配合服务发现一起用。
偶然通过一位同事了解到Spring Boot也可以直接整合Feign进行Http远程调用,赶紧试了一把尝尝鲜,果断鸟枪换炮。感谢小伙伴的分享~
话不多说直接show code。
建立一个SpringBoot应用的过程不再赘述了,基于IDEA创建一个新的工程还是蛮快的。
在Pom.xml中添加如下依赖
<dependency> <groupId>org.springframework.boot</groupId> <artifactId>spring-boot-starter-web</artifactId> </dependency> <dependency> <groupId>org.springframework.cloud</groupId> <artifactId>spring-cloud-starter-openfeign</artifactId> </dependency> <!-- https://mvnrepository.com/artifact/io.github.openfeign/feign-okhttp --> <dependency> <groupId>io.github.openfeign</groupId> <artifactId>feign-okhttp</artifactId> <version>10.2.3</version> </dependency>
由于feign自带的http客户端实现是HttpURLConnection,没有连接池功能,可配置能力也比较差,因此我们使用okhttp作为底层的http客户端的具体实现。
编写一个FeignOkHttpConfig配置类,配置OkHttpi实例。
@Configuration @ConditionalOnClass(Feign.class) @AutoConfigureBefore(FeignAutoConfiguration.class) public class FeignOkHttpConfig { @Bean public okhttp3.OkHttpClient okHttpClient(){ return new okhttp3.OkHttpClient.Builder() .readTimeout(60, TimeUnit.SECONDS) .connectTimeout(60, TimeUnit.SECONDS) .writeTimeout(120, TimeUnit.SECONDS) .connectionPool(new ConnectionPool()) .build(); } }
主要设置了链接超时时间及读写超时时间,这里是笔者随意写的,具体业务中使用需要根据业务特点去灵活调整。
笔者为了测试方便,直接在博客的某个路径下放置了一个json文件,文件内容如下:
{ "code": "10000", "desc": "success", "data": { "name": "snowalker", "age": "18" } }
我们接着编写Feign客户端对此json文件发起调用:
@FeignClient(name = "feignClientProxy",url = "http://wuwenliang.net/samples/") public interface FeignClientProxy { @RequestMapping(value = "/snowalker.json", method = RequestMethod.GET) @ResponseBody ResponseData<DemoResp> invoke(@RequestParam(value="name") String name); /** * 容错处理类,当调用失败时 返回空字符串 */ @Component class DefaultFallback implements FeignClientProxy { @Override public ResponseData<DemoResp> invoke(@RequestParam(value="snowalker") String name){ return new ResponseData<DemoResp>().setCode("40004").setDesc("服务异常").setData(null); } } }
这里主要关注注解 @FeignClient ,参数name用以指定bean实例名,url用以指定远程服务调用根路径。
在具体的方法上标注@RequestMapping,指定资源的相对路径以及调用的方法。
@Controller @RequestMapping("/demo") public class FeignDemoController { @Autowired FeignClientProxy feignClientProxy; @RequestMapping(value = "feign") @ResponseBody public String testFeign(@RequestParam(name = "name") String name) throws JsonProcessingException { ObjectMapper objectMapper = new ObjectMapper(); ResponseData<DemoResp> respResponseBody = feignClientProxy.invoke(name); return "调用结果:" + objectMapper.writeValueAsString(respResponseBody); } }
这个代码就很简单了,不需要多解释,就是接收参数name直接透传Feign客户端(通过@Autowired注解注入),发起远程调用,将调用结果(json反序列化后的实体)打印出来。
启动该demo服务,访问FeignDemoController.testFeign的mapping路径:
http://localhost:8080/demo/feign?name=123
可以看到如下返回参;
调用结果:{"code":"10000","desc":"success","data":{"name":"snowalker","age":"18"}}
具体访问效果截图如下:
可以看到,我们的feign客户端成功的发起了对远程资源的访问。
PS: 本文涉及到的源码已经发布到笔者的github,感兴趣的同学可以自行下载体验。
源码地址
本文主要是实战,目的为整合纯Spring Boot与Feign,并进行一次尝鲜式的测试。在实战中,需要根据不同的远程接口对Feign客户端做对应的定义,但总的来讲,这种开发方式极大的提升了外部接口的接入速率,对于提升开发效率、增加代码的优雅程度都大有裨益。
立个flag,后面的文章中,我们将对Feign是如何调用远程资源的机理进行深入的分析。毕竟要知其然,还要知其所以然。
版权声明:
原创不易,洗文可耻。除非注明,本博文章均为原创,转载请以链接形式标明本文地址。