在项目中咱们有时候须要调用第三方的 API
,微服务架构中这种状况则更是没法避免——各个微服务之间通讯。好比通常的项目中,有时候咱们会使用 HTTP Client 发送 HTTP 请求来进行调用,而在微服务架构,Spring Cloud 全家桶中,Spring Cloud Feign 则是更常见的选择。那么,我如何只使用 Spring Cloud Feign 而不引入整个 Spring Cloud 呢?这就要从一个渣男语录 API
提及了……java
API
呢?免费的 API
特别多,github
上也有免费 API
地址汇总的 repo
,但这些都太正式了。有趣的事物老是会相互吸引的,无心间我发现了这么一个网站,“渣男:说话的艺术”(lovelive.tools/) ,每次请求均可以获取一句甜言蜜语(渣男语录),这不正是我这个钢铁直男须要的吗?并且特别良心的是,做者提供了 API
列表,给做者点赞!git
首先,咱们先快速构建一个 Spring Boot 的 web 项目,这里我就省略了。而后在咱们 gradle
文件中添加 spring-cloud-starter-openfeign
依赖:github
compile group: 'org.springframework.cloud', name: 'spring-cloud-starter-openfeign', version: '2.1.3.RELEASE' 复制代码
而后,在启动类添加响应的注解 @EnableFeignClients
:web
@SpringBootApplication @EnableFeignClients public class MyOpenFeignApplication { public static void main(String[] args) { SpringApplication.run(MyOpenFeignApplication.class, args); } } 复制代码
接着,咱们即可以配置咱们的 Client 了,咱们先建立一个接口类,好比叫 BadGuyFeignClient
,并声明为 FeignClient
:spring
@FeignClient public interface BadGuyFeignClient { } 复制代码
@FeignClient
有如下几个较经常使用属性:编程
name
,value
:指定 FeignClient
的名称,若是项目使用了 Ribbon
,name
属性会做为微服务的名称,用于服务发现;url
:url
通常用于调试,能够手动指定 @FeignClient
调用的地址fallback
,fallbackFactory
:fallback
定义容错的处理类,当调用远程接口失败或超时时,会调用对应接口的容错逻辑,fallback
指定的类必须实现 @FeignClient
标记的接口;fallbackFactory
工厂类,用于生成 fallback
类示例,经过这个属性咱们能够实现每一个接口通用的容错逻辑,减小重复的代码;configuration
:Feign
配置类,能够自定义 Feign
的 Encoder
、Decoder
、LogLevel
、Contract
;path
:定义当前 FeignClient
的统一前缀。而后,咱们即可以配置对应的属性,这里咱们只是用来实现相似于 HTTP Client 的功能,因此只是简单配置了 url
和 path
这些属性:api
@FeignClient(name = "badGuy", url = "${bab.guy.url}", path = "api") public interface BadGuyFeignClient { /** * 随机获取一句甜言蜜语 * * @return */ @GetMapping("SweetNothings") String getSweetNothings(); /** * 获取 count 条甜言蜜语 * * @param count 获取甜言蜜语条数 * @return Json 格式的结果 */ @GetMapping("SweetNothings/{count}/Serialization/Json") QuotationResult<String> getSweetNothingsJsonByCount(@PathVariable("count") Integer count); } 复制代码
声明为 FeignClient
以后,咱们即可以在代码中使用 @Resource
或者 @Autowire
进行注入使用了:markdown
@Component public class BadServiceImpl implements BadGuyService { @Autowired private BadGuyFeignClient badGuyFeignClient; @Override public List<String> getQuotations(Integer count) { if (count == null || count <= 0) { String singleQuotation = badGuyFeignClient.getSweetNothings(); return new ArrayList<String>() {{ add(singleQuotation); }}; } return badGuyFeignClient.getSweetNothingsJsonByCount(count).getReturnObj(); } } 复制代码
而后 Controller
中是这么写的:架构
@GetMapping({"quotations", "quotations/{count}"}) public ResultWrapper<List<String>> getBadGuyQuotations( @PathVariable(value = "count", required = false) Integer count ) { try { List<String> resultStrings = badGuyService.getQuotations(count); return new ResultWrapper<>(resultStrings); } catch (Exception e) { log.error("Failed to get bad guy quotations.", e); return new ResultWrapper<List<String>>() {{ setCode("1000002"); setMessage("error"); setData(null); }}; } } 复制代码
启动项目以后,咱们能够访问 http://localhost:8088/api/badGuy/quotations 或者 http://localhost:8088/api/badGuy/quotations/10 后面跟数字,便可获得对应条目数的结果。(完整项目地址在文末)app
FeignClient
与 HttpClient
的区别是什么?HttpClient
与之一样实现的还有 Okhttp
、Httpurlconnection
、RestTemplate
等等,其 URL 参数是以编程方式构造的,数据被发送到其余服务。在更复杂的状况下,咱们将不得不RestTemplate
深刻到更低级别的 API
提供的甚至是 API
的细节。
FeignClient
则更像是在基于 REST 的服务调用上提供更高级别的抽象,在客户端编写声明式 REST 服务接口,并使用这些接口来编写客户端程序。开发人员不用担忧这个接口的实现。这将在运行时由 Spring 动态配置。经过这种声明性的方法,开发人员不须要深刻了解由 HTTP 提供的 HTTP 级别 API
的细节的RestTemplate
。
总的来说,FeignClient
更具抽象性,也更简单、灵活。
本文简单介绍了如何使用 Spring Cloud Feign
组件来替代 HttpClient
来实现调用第三方服务的方法,除了集成 Feign
组件,咱们也能够在项目中加入 Ribbon
用于服务发现,加入 Hystrix
用于服务熔断等等,这样就会完整地构建出一个基本服务了。
项目地址: github.com/lq920320/my…