Spring Cloud Feign Clients 无需 Controller自动暴露Restful接口
前言
在开发SpringCloud应用中,Feign作为声明式调用的事实标准极大的简化了Rest远程调用,提供了类本地化的调用方式。服务提供方的接口暴露方式是通过Controller暴露Restful,而在这个Controller的代码现实中大部分都是处理请求然后再调用Service中的方法,是一个比较模板化的功能,但是工作量确不少。本文介绍一种通过动态代理的方式无需Controller直接暴露Restful接口。
本文中使用笔者在Github开源的框架来实现,本文的讲解也在这个框架基础之上来说明
Git路径:https://github.com/leecho/spr...
依赖
<dependency><groupId>com.github.leecho</groupId><artifactId>spring-cloud-starter-feign-proxy</artifactId><version>{last-version}</version></dependency>
实现
定义Service Interface
首先定义服务接口,使用@FeignClient标示是一个Feign接口,在这个示例Sevice中定义了CURD和文件上传方法,并使用了一些常用参数注解
@Api(tags = "DemoService", description = "Demo Feign Client")
@FeignClient("demo-service")
public interface DemoService {/*** create demo** @param demo* @return*/@ApiOperation(value = "Create demo")@PostMapping(value = "/demo")Demo create(@RequestBody @Valid @ApiParam Demo demo);/*** update demo** @param demo* @return*/@PutMapping(value = "/demo")Demo update(@RequestBody @Valid Demo demo);/*** delete demo** @param id* @return*/@DeleteMapping(value = "/demo/{id}")Demo delete(@PathVariable(name = "id") String id);/*** list demo** @param id* @param headerValue test header value* @return*/@GetMapping(value = "/demo/{id}")Demo get(@PathVariable(name = "id") String id, @RequestHeader(name = "header") String headerValue);/*** list demos** @return*/@GetMapping(value = "/demos")List<Demo> list();/*** upload file** @param file* @return*/@PostMapping(value = "/demo/upload")String upload(@RequestPart(name = "file") MultipartFile file);
}
实现Service
在实现类中简单的实现了CURD和上传文件的方法
@Slf4j
@Primary
@Service
public class DemoServiceImpl implements DemoService {@Overridepublic Demo create(Demo demo) {log.info("Create executed : " + demo);return demo;}@Overridepublic Demo update(Demo demo) {log.info("Update execute :" + demo);return demo;}@Overridepublic Demo delete(String id) {log.info("Delete execute : " + id);return Demo.builder().name("demo-" + id).data("data-" + id).build();}@Overridepublic Demo get(String id, String header) {Demo demo = Demo.builder().name(header).data(header).build();System.out.println("Get execute : " + id + "," + header);return demo;}@Overridepublic List<Demo> list() {System.out.println("List execute");List<Demo> demos = new ArrayList<>();for (int i = 0; i < 5; i++) {Demo demo = Demo.builder().name("demo-" + i).data("data" + i).build();demos.add(demo);}return demos;}@Overridepublic String upload(MultipartFile file) {return file.getOriginalFilename();}
}
动态生成Restful接口的原理是动态生成Controller类实现ServiceInterface,如果真正的实现类会被其他BEAN依赖,需要通过注解@Primary来方式来防止依赖冲突
配置应用
在应用中通过@EnableFeignProxies来标示应用在启动的过程中会扫描所有的FeignClients并暴露Restful接口
@EnableFeignProxies(basePackages = "com.github.leecho")
@ComponentScan("com.github.leecho")
@SpringBootApplication
public class DemoApplication {public static void main(String[] args) {SpringApplication.run(DemoApplication.class, args);}}
测试用例
在测试用例中对Service的接口进行测试
@SpringBootTest
@RunWith(SpringJUnit4ClassRunner.class)
@WebAppConfiguration
public class DemoApplicationTest {@Autowiredprivate WebApplicationContext context;private MockMvc mvc;@Beforepublic void setUp() {mvc = MockMvcBuilders.webAppContextSetup(context).build();}@Testpublic void create() throws Exception {mvc.perform(MockMvcRequestBuilders.post("/demo").contentType(MediaType.APPLICATION_JSON_UTF8).content(new ObjectMapper().writeValueAsString(Demo.builder().name("create").data("data").build())).accept(MediaType.APPLICATION_JSON)).andExpect(MockMvcResultMatchers.status().isOk()).andDo(MockMvcResultHandlers.print());}@Testpublic void update() throws Exception {mvc.perform(MockMvcRequestBuilders.put("/demo").contentType(MediaType.APPLICATION_JSON_UTF8).content(new ObjectMapper().writeValueAsString(Demo.builder().name("update").data("data").build())).accept(MediaType.APPLICATION_JSON)).andExpect(MockMvcResultMatchers.status().isOk()).andDo(MockMvcResultHandlers.print());}@Testpublic void delete() throws Exception {mvc.perform(MockMvcRequestBuilders.delete("/demo/{id}", "1").contentType(MediaType.APPLICATION_JSON_UTF8).accept(MediaType.APPLICATION_JSON)).andExpect(MockMvcResultMatchers.status().isOk()).andDo(MockMvcResultHandlers.print());}@Testpublic void get() throws Exception {mvc.perform(MockMvcRequestBuilders.get("/demo/{id}", "1").contentType(MediaType.APPLICATION_JSON_UTF8).header("header", "header-value").accept(MediaType.APPLICATION_JSON)).andExpect(MockMvcResultMatchers.status().isOk()).andDo(MockMvcResultHandlers.print());}@Testpublic void list() throws Exception {mvc.perform(MockMvcRequestBuilders.get("/demos").contentType(MediaType.APPLICATION_JSON_UTF8).accept(MediaType.APPLICATION_JSON)).andExpect(MockMvcResultMatchers.status().isOk()).andDo(MockMvcResultHandlers.print());}@Testpublic void upload() throws Exception {mvc.perform(MockMvcRequestBuilders.multipart("/demo/upload").file(new MockMultipartFile("file", "test.txt", ",multipart/form-data", "upload test".getBytes())).accept(MediaType.APPLICATION_JSON)).andExpect(MockMvcResultMatchers.status().isOk()).andDo(MockMvcResultHandlers.print());}
}
在启动日志中也可以看到Restful接口已经暴露成功。
后语
关于这个框架的介绍,后续详细的给大家进行介绍。文中所涉及到的代码也在Git中:spring-cloud-feign-proxy-sample
Spring Cloud Feign Clients 无需 Controller自动暴露Restful接口相关推荐
- Spring Cloud的负载均衡Spring Cloud Ribbon和Spring Cloud Feign
一.客户端负载均衡:Spring Cloud Ribbon. Spring Cloud Ribbon是基于HTTP和TCP的客户端负载工具,它是基于Netflix Ribbon实现的.通过Spring ...
- Spring Cloud Feign使用详解
通过前面两章对Spring Cloud Ribbon和Spring Cloud Hystrix的介绍,我们已经掌握了开发微服务应用时,两个重要武器,学会了如何在微服务架构中实现客户端负载均衡的服务调 ...
- Spring Cloud Feign传输Header,并保证多线程情况下也适用
Spring Cloud Feign传输Header,并保证多线程情况下也适用 一.现象 微服务在生产中,常遇到需要把 header 传递到下一子服务的情况(如服务A访问服务B的接口,需要传递head ...
- Spring Cloud Feign原理详解
目录 1.什么是Feign? 2.Open Feign vs Spring Cloud Feign 2.1.OpenFeign 2.2.Spring Cloud Open Feign 3.Spring ...
- Spring Cloud Feign - 内部实现细节
1. 概述 Feign用于服务间调用,它的内部实现是一个包含Ribbon(负载均衡)的JDK-HttpURLConnection(Http)调用.虽然调用形式是类似于RPC,但是实际调用是Http,这 ...
- Spring Cloud Feign 请求压缩 、Feign的日志级别配置
一.Spring Cloud Feign 请求压缩 #开启压缩compression:request:enabled: true # 开启请求压缩#最小触发压缩的大小min-request-size: ...
- k8s springboot 文件_Springboot整合Spring Cloud Kubernetes读取ConfigMap支持自动刷新配置的教程...
1 前言 欢迎访问南瓜慢说 www.pkslow.com获取更多精彩文章! Docker & Kubernetes相关文章:容器技术 之前介绍了Spring Cloud Config的用法,但 ...
- Spring Cloud Feign 1(声明式服务调用Feign 简介)
Spring Cloud Feign基于Netflix Feign 同时整合了Spring Cloud Ribbon和Spring Cloud Hytrix,除了提供两者的强大功能外,它还提供了一种声 ...
- Spring Cloud Feign 请求时附带请求头
Spring Cloud Feign 请求时附带请求头 问题描述 解决方案 FeignConfiguration 使用 配置修改 问题描述 Feign 在请求时是不会将 request 的请求头带着请 ...
最新文章
- 根据DNS的A记录负载均衡web服务请求
- 成功解决ValueError: setting an array element with a sequence.
- [你必须知道的.NET] 第二回:对抽象编程:接口和抽象类
- 美团客户端响应式框架 EasyReact 开源啦
- 当你输入一个网址的时候,实际会发生什么?(转)
- Awesome Go
- 普通类创建获取session 方式_Springboot系列之RestApi中获取枚举类属性的几种方式...
- 如何为自定义的控件在工具箱中自定义个性化的图标
- 一个月的java工作总结
- 误删MySQL数据库中的mysql库怎么恢复
- 51单片机 驱动有源/无源蜂鸣器+Proteus仿真
- Linux编程基础期末冲刺——第3章用户组与用户组管理
- hdu 3987 - 最小割最少割边
- OAuth2授权原理
- 2019年终总结2020个人规划和目标
- 《Word中从正文开始设置页码》
- 苹果vs剪辑下载_Vlog教程 | 如何在手机剪辑app中添加自己的音乐?
- RAR Extractor - The Unarchiver Pro for mac(解压缩软件)
- mysql如何不停机迁移_如何实现真正的不停机数据迁移?
- 青春三部曲(《且听风吟》,《一九七三年的弹子球》,《寻羊冒险记》)--[日]村上春树...