转载

SpringBoot2.x直接整合Feign实现远程接口调用[尝鲜]

之前也用过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客户端的具体实现。

配置OkHttp

编写一个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();
    }
}

主要设置了链接超时时间及读写超时时间,这里是笔者随意写的,具体业务中使用需要根据业务特点去灵活调整。

编写FeignClient接口

笔者为了测试方便,直接在博客的某个路径下放置了一个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,指定资源的相对路径以及调用的方法。

编写一个本地测试接口,调用Feign客户端

@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"}}

具体访问效果截图如下:

SpringBoot2.x直接整合Feign实现远程接口调用[尝鲜]

可以看到,我们的feign客户端成功的发起了对远程资源的访问。

PS: 本文涉及到的源码已经发布到笔者的github,感兴趣的同学可以自行下载体验。

源码地址

小结

本文主要是实战,目的为整合纯Spring Boot与Feign,并进行一次尝鲜式的测试。在实战中,需要根据不同的远程接口对Feign客户端做对应的定义,但总的来讲,这种开发方式极大的提升了外部接口的接入速率,对于提升开发效率、增加代码的优雅程度都大有裨益。

立个flag,后面的文章中,我们将对Feign是如何调用远程资源的机理进行深入的分析。毕竟要知其然,还要知其所以然。

版权声明:

原创不易,洗文可耻。除非注明,本博文章均为原创,转载请以链接形式标明本文地址。

原文  http://wuwenliang.net/2019/07/24/SpringBoot2.x直接整合Feign实现远程接口调用[尝鲜]/
正文到此结束
Loading...