Spring Cloud OpenFeign模版化客户端
OpenFeign是什么?
OpenFeign是一个显示声明式的WebService客户端。使用OpenFeign能让编写Web Service客户端更加简单。使用时只需定义服务接口,然后在上面添加注解。OpenFeign也支持可拔插式的编码和解码器。spring cloud对feign进行了封装,使其支持MVC注解和HttpMessageConverts。和eureka(服务注册中心)和ribbon组合可以实现负载均衡。在Spring Cloud中使用OpenFeign,可以做到使用HTTP请求访问远程服务,就像调用本地方法一样的,开发者完全感知不到这是在调用远程方法,更感知不到在访问HTTP请求,非常的方便。
OpenFeign能干啥?
- OpenFeign的设计宗旨式简化Java Http客户端的开发。Feign在restTemplate的基础上做了进一步的封装,由其来帮助我们定义和实现依赖服务接口的定义。在OpenFeign的协助下,我们只需创建一个接口并使用注解的方式进行配置(类似于Dao接口上面的Mapper注解)即可完成对服务提供方的接口绑定,大大简化了Spring cloud Ribbon的开发,自动封装服务调用客户端的开发量。
- OpenFeign集成了Ribbon,利用ribbon维护了服务列表,并且通过ribbon实现了客户端的负载均衡。与ribbon不同的是,通过OpenFeign只需要定义服务绑定接口且以申明式的方法,优雅而简单的实现了服务调用。
OpenFeign使用
使用OpenFeign之前,我们首先将之前的工程还原,为了操作简单,我们只采用单节点的eureka。
API服务模块搭建
由于我们使用openfeign之后,需要暴露相关接口给外部服务,所以我们需要写一个api服务。
我这里为了方便所以直接在外部创建了一个ms-service-api
服务,实际开发过程中我们基本都是将其写在对应的模块中。
整体模块创建完成后,我们便可以定义相关接口供外部调用了,每个服务一一对应即可。
这里只演示一个goods-service-api
项目的搭建,项目代码在文末会给出。
引入依赖
引入 open feign的相关依赖。
<dependency> <groupId>org.springframework.cloud</groupId> <artifactId>spring-cloud-starter-openfeign</artifactId> </dependency>
创建接口
这里对应的是goods-service
项目中的GoodsService类,这里定义了其中的方法。
public interface IGoodsService { @GetMapping("/goods") String getGoodsById(); }
这个时候还需要将goods-service
项目的类继承该接口:
首先需要将我们创建的api
服务依赖添加到项目中:
<dependency> <groupId>com.example</groupId> <artifactId>goods-service-api</artifactId> </dependency>
然后开始修改:
@Slf4j @RestController public class GoodsService implements IGoodsService { @Value("${server.port}") private String port; /** * 根据ID查询商品信息 * * @return */ @GetMapping("/goods") public String getGoodsById() { log.info("收到请求,端口为:{}", port); return "返回商品信息"; } }
这里为了区分职责,类似我们写mapper和service这种,又额外写了一个对外暴露的接口。
FeignClient
中的name不能随意写,它对应各个服务在eureka中注册的名字。如果不写该接口的话,可以将该注解加在IGoodsService
上。
@FeignClient(name = "goods-service") public interface IGoodsServiceFeignClient extends IGoodsService { }
以上便是一个api服务的搭建过程。
外部调用
当我们的API服务调用完成之后,如何在聚合服务中调用呢?
首先我们需要在聚合服务中引入openfeign
以及各api
服务的依赖:
<!-- open fiegn--> <dependency> <groupId>org.springframework.cloud</groupId> <artifactId>spring-cloud-starter-openfeign</artifactId> </dependency> <dependency> <groupId>com.example</groupId> <artifactId>goods-service-api</artifactId> </dependency> <dependency> <groupId>com.example</groupId> <artifactId>marking-service-api</artifactId> </dependency> <dependency> <groupId>com.example</groupId> <artifactId>order-service-api</artifactId> </dependency>
引入相关依赖后,我们就可以不需要之前的代码了,全面采用面向接口的形式来开发。
@RestController @RequestMapping("/order") @Slf4j public class OrderController { // 代理对象 @Autowired private IGoodsService goodsService; @Autowired private IPromotionService promotionService; @Autowired private IOrderService orderService; @GetMapping public String order() { log.info("begin do order"); // 使用openfiegn String goods = goodsService.getGoodsById(); String promotion = promotionService.getPromotionById(); String result = orderService.createOrder(goods, promotion); return result; } }
这个时候还没有完全结束,我们还需要在启动类上配置扫码相关的feign
类。
@EnableFeignClients(basePackages = "com.example.feignclient") @SpringBootApplication public class MallProtalApplication { public static void main(String[] args) { SpringApplication.run(MallProtalApplication.class, args); } }
以上便是我们集成openfeign
的全部步骤。
项目代码
OpenFeign相关特性 Gzip压缩Looger底层通信框架:(sun.net.www.protocol.http.HttpURLConnection)也可以自定义替换为OKHttp Logger 日志使用
使用OpenFeign的日志功能,我们需要进行如下几个操作:
创建配置类
@Configurationpublic class FeignClientLogConfiguration { /** * NONE * BASIC * HEAD * FULL * @return */ @Bean Logger.Level feignLogger(){ return Logger.Level.FULL; }}
指定配置类
@FeignClient(name = "goods-service",configuration = FeignClientLogConfiguration.class)public interface IGoodsServiceFeignClient extends IGoodsService {}
最后还需要在聚合服务出添加相关日志配置
feignclient所在的路径
# openfeign 日志logging.level.[com.example.feignclient]=DEBUG
使用OKHttp通信
引入依赖
<!-- ophttp--> <dependency> <groupId>io.github.openfeign</groupId> <artifactId>feign-okhttp</artifactId> </dependency>
修改配置
# openfeign替换底层通信框架feign.httpclient.enabled=falsefeign.okhttp.enabled=true