Spring Cloud学习系列第四篇声明式服务调用
Posted yipaihushuo
tags:
篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了Spring Cloud学习系列第四篇声明式服务调用相关的知识,希望对你有一定的参考价值。
之前的随笔我们访问其它微服务方式都是通过Ribbon组件提供的一些模板方法去访问的,使用过程中会发现一个问题就是对某服务接口调用往往不是一处的,于是我们需要这个服务接口进行一个封装,其它地方统一调用这个封装,而每个封装其实也就是对用RestTemplate的模板方法对目标服务接口的调用,这样代码里就会有很多冗余的RestTemplate方法了,代码很不优雅,而使用了Spring Cloud Feign就不一样了,它是Spring Cloud Hystrix和Spring Cloud Ribbon整合,有了它在框架层面Spring Cloud就帮我们封装好这些东西了,我们只需要定义一个需要访问目标服务方法的接口,就可以直接通过依赖注入直接使用了,省去了我们自己封装那一步,代码也更加优雅了。
下面改写一下之前的例子,体验一下吧。我们新增一个Feign项目作为采用声明式服务调用这种方式去访问ServiceA的服务。由于Feign需要定义访问ServiceA方法的接口,然后ServiceA需要提供对应的HTTP服务,于是我们在新增一个FeignApi项目把公共的接口定义在这,然后Feign和ServiceA依赖FeignApi,达到代码共用的效果。结合下代码来理解下。
一、 新增FeignApi项目
再次说明FeigApi作用了抽取共用代码给Feign和ServiceA使用的,哪里会有共用代码?这就是需要Feign需要访问的ServiceA的几个接口信息 。
FeignService接口定义需要访问的URL路径。
package com.pumpkin.service;
import com.pumpkin.dto.User;
import org.springframework.web.bind.annotation.*;
@RequestMapping("/user")
public interface FeignService {
@RequestMapping(value = "/hello1.do", method = RequestMethod.GET)
String hello(@RequestParam("name") String name);
@RequestMapping(value = "/hello2.do", method = RequestMethod.GET)
User hello(@RequestParam("name") String name, @RequestParam("sex") Integer sex);
@RequestMapping(value = "/hello3.do", method = RequestMethod.POST)
String hello(@RequestBody User user);
}
二、Feign项目使用声明式调用
写个controller作为等下我们调用ServcieA的入口,URL为:127.0.0.1:7000/feign/hello.do
spring.application.name=feign
#eureka.instance.instance-id=${spring.application.name}:${random.int}
server.port=7000
eureka.client.serviceUrl.defaultZone=http://localhost:5001/eureka/,http://localhost:5002/eureka/
package com.pumpkin.controller;
import com.netflix.hystrix.contrib.javanica.annotation.HystrixCommand;
import com.pumpkin.dto.User;
import com.pumpkin.service.FeignService;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RequestMethod;
import org.springframework.web.bind.annotation.RestController;
@RestController
@RequestMapping("/feign")
public class FeignController {
@Autowired
private FeignService feignService;
@RequestMapping(value = "/hello.do", method = RequestMethod.GET)
public String feignHello() {
StringBuilder sb = new StringBuilder();
sb.append(feignService.hello("MIMI")).append("
");
sb.append(feignService.hello("MIMI", 20)).append("
");
sb.append(feignService.hello(new User("MIMI", 20))).append("
");
return sb.toString();
}
}
编写FeignServiceImpl接口,因为FeignService在FeignApi项目,所以我们要先依赖FeignApi项目。然后FeignServiceImpl只需要继承FeignService,并添加@FeignClient(value = "SERVICE-A")注解后就可以通过依赖注入给Controller层的入口使用了。
package com.pumpkin.service.impl;
import com.pumpkin.service.FeignService;
import org.springframework.cloud.netflix.feign.FeignClient;
@FeignClient(value = "SERVICE-A")
public interface FeignServiceImp extends FeignService {
}
三、改造ServiceA项目
新增一个FeignController提供对外服务。可以看到FeignController是通过实现FeignService接口,这样ServiceA项目就不需要冗余那个几个方法的代码了,直接依赖FeignApi即可。
package com.pumpkin.controller;
import com.pumpkin.dto.User;
import com.pumpkin.service.FeignService;
import org.apache.log4j.Logger;
import org.springframework.web.bind.annotation.RequestBody;
import org.springframework.web.bind.annotation.RequestParam;
import org.springframework.web.bind.annotation.RestController;
@RestController
public class FeignController implements FeignService {
private final Logger LOGGER = Logger.getLogger(getClass());
@Override
public String hello(@RequestParam("name")String name) {
return "hello";
}
@Override
public User hello(@RequestParam("name")String name, @RequestParam("sex")Integer sex) {
LOGGER.info("name=" +name+ " ,sex=" +sex);
return new User("pumpkin", 0);
}
@Override
public String hello(@RequestBody User user) {
return "hello user=" +user.toString();
}
}
四、启动看看效果
五、总结
Spring Cloud Feign是对Spring Cloud Ribbon和Spring Hystrix封装整合。这篇随笔主要介绍了Spring Cloud Feign的简单使用,对于如何进行服务熔断和降级并没有涉及,但从使用层面来讲也就是几个注解的问题,只要对Hystrix机制有一定的理解,使用起来是非常容易的,另外Feign并没有对Hysrix的请求合并和请求缓存进行封装,所以需要这些功能的话,只能使用回Ribbon了。
六、参考资料
Spring Cloud微服务实战-翟永超。本系列的学习都是参考该书籍学习的,同时源码使用的Spring Boot和Spring Cloud的版本也与该书保持一致。
七、源码
码云地址:[email protected]:pumpkingg/Spring-Cloud-Study.git 该篇随笔对应的代码是master分支下命名为blog3的Tag
以上是关于Spring Cloud学习系列第四篇声明式服务调用的主要内容,如果未能解决你的问题,请参考以下文章
Spring Data JPA系列4:Spring声明式事务处理与多数据源支持
Spring Cloud Eureka 分布式开发之服务注册中心负载均衡声明式服务调用实现
Spring Cloud学习笔记-007
[第四篇]——Windows Docker 安装之Spring Cloud直播商城 b2b2c电子商务技术总结
Spring Cloud Gateway面试攻略,微服务网关的作用以及案例
Spring Boot Serverless 实战系列 | 性能调优