Spring Cloud Feign(声明式服务调用)(1)

清疚 2022-05-11 10:14 272阅读 0赞

Spring Cloud Feign它基于Netflix Feign实现,整合了Spring Cloud Ribbon与Spring Cloud Hystrix,除了提供这两者的强大功能,它还提供了一种声明式的Web服务客户端定义方式。

1.下面首先创建一个Spring Boot基础工程取名为feign-consumer并在其pom.xml文件中加入spring-cloud-starter-eureka和spring-cloud-starter-feign依赖。

  1. <?xml version="1.0" encoding="UTF-8"?>
  2. <project xmlns="http://maven.apache.org/POM/4.0.0" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
  3. xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd">
  4. <modelVersion>4.0.0</modelVersion>
  5. <groupId>com.example</groupId>
  6. <artifactId>feign-consumer</artifactId>
  7. <version>0.0.1-SNAPSHOT</version>
  8. <packaging>jar</packaging>
  9. <name>feign-consumer</name>
  10. <description>Demo project for Spring Boot</description>
  11. <parent>
  12. <groupId>org.springframework.boot</groupId>
  13. <artifactId>spring-boot-starter-parent</artifactId>
  14. <version>2.0.5.RELEASE</version>
  15. <relativePath/> <!-- lookup parent from repository -->
  16. </parent>
  17. <properties>
  18. <project.build.sourceEncoding>UTF-8</project.build.sourceEncoding>
  19. <project.reporting.outputEncoding>UTF-8</project.reporting.outputEncoding>
  20. <java.version>1.8</java.version>
  21. <spring-cloud.version>Finchley.SR1</spring-cloud.version>
  22. </properties>
  23. <dependencies>
  24. <dependency>
  25. <groupId>org.springframework.cloud</groupId>
  26. <artifactId>spring-cloud-starter-netflix-eureka-client</artifactId>
  27. </dependency>
  28. <dependency>
  29. <groupId>org.springframework.cloud</groupId>
  30. <artifactId>spring-cloud-starter-openfeign</artifactId>
  31. </dependency>
  32. <dependency>
  33. <groupId>org.springframework.boot</groupId>
  34. <artifactId>spring-boot-starter-web</artifactId>
  35. </dependency>
  36. <dependency>
  37. <groupId>org.springframework.boot</groupId>
  38. <artifactId>spring-boot-starter-test</artifactId>
  39. <scope>test</scope>
  40. </dependency>
  41. </dependencies>
  42. <dependencyManagement>
  43. <dependencies>
  44. <dependency>
  45. <groupId>org.springframework.cloud</groupId>
  46. <artifactId>spring-cloud-dependencies</artifactId>
  47. <version>${spring-cloud.version}</version>
  48. <type>pom</type>
  49. <scope>import</scope>
  50. </dependency>
  51. </dependencies>
  52. </dependencyManagement>
  53. <build>
  54. <plugins>
  55. <plugin>
  56. <groupId>org.springframework.boot</groupId>
  57. <artifactId>spring-boot-maven-plugin</artifactId>
  58. </plugin>
  59. </plugins>
  60. </build>
  61. </project>

2.在主类上添加@EnableFeignClients注解开启Spring Cloud Feign的支持功能:

  1. @SpringBootApplication
  2. @EnableFeignClients
  3. @EnableDiscoveryClient
  4. public class FeignConsumerApplication {
  5. public static void main(String[] args) {
  6. SpringApplication.run(FeignConsumerApplication.class, args);
  7. }
  8. }

3.定义HelloService接口,通过@FeignClient注解指定服务名来绑定服务,然后使用Spring MVC的注解来绑定具体该服务提供的REST接口。

  1. @FeignClient("hello-service")//用于绑定名为hello-service服务
  2. public interface HelloService {
  3. @RequestMapping("/hello")
  4. public String hello(String id);
  5. }

4.最后创建一个控制器来实现对Feign客户端的调用。使用@AutoWired直接注入HelloService实例,并在该控制器中直接调用hello-service服务发起的/hello接口的调用。

  1. @RestController
  2. public class ConsumerController {
  3. @Autowired
  4. HelloService helloService;
  5. @GetMapping("/feign-consumer")
  6. public String helloConsumer(String id){
  7. return helloService.hello(id);
  8. }
  9. }

5.修改application.properties文件:

  1. spring.application.name=feign-consumer
  2. server.port=9001
  3. eureka.client.serviceUrl.defaultZone=http://localhost:1111/eureka/

70

70 1

70 2

不过此时是没有参数绑定能力的所以没有打印id。

参数绑定

首先扩展一下服务提供者(hello-service)。

  1. @RestController
  2. public class HelloController {
  3. private final Logger logger=Logger.getLogger(getClass());
  4. @RequestMapping("/hello")
  5. public String index() throws InterruptedException {
  6. // int sleepTime=new Random().nextInt(3000);
  7. // logger.info("sleep:"+sleepTime);
  8. // Thread.sleep(sleepTime);
  9. logger.info(new Date());
  10. return "Hello"+new Date()+"---"+new Random().nextInt();
  11. }
  12. @RequestMapping(value = "/hello1", method = RequestMethod.GET)
  13. public String hello1(@RequestParam String name) {
  14. return "hello " + name + "!";
  15. }
  16. @RequestMapping(value = "/hello2", method = RequestMethod.GET)
  17. public Map<String,Object> hello2(@RequestHeader String name, @RequestHeader String author, @RequestHeader Integer price) throws UnsupportedEncodingException {
  18. Map<String,Object> map = new HashMap<String,Object>();
  19. map.put("name",URLDecoder.decode(name));
  20. map.put("author",URLDecoder.decode(author));
  21. return map;
  22. }
  23. @RequestMapping(value = "/hello3", method = RequestMethod.POST)
  24. public String hello3(@RequestBody Map<String,Object> book) {
  25. return "书名为:" + book.get("name") + ";作者为:" + book.get("author");
  26. }
  27. @RequestMapping(value = "/hello4", method = RequestMethod.POST)
  28. public String hello4(@RequestBody User user) {
  29. return "用户名:" + user.getName() + ";年龄为:" + user.getAge();
  30. }
  31. }

User类:

  1. public class User {
  2. private String name;
  3. private Integer age;
  4. public User(){}
  5. public User(String name, Integer age){
  6. this.name=name;
  7. this.age=age;
  8. }
  9. public String getName() {
  10. return name;
  11. }
  12. public void setName(String name) {
  13. this.name = name;
  14. }
  15. public Integer getAge() {
  16. return age;
  17. }
  18. public void setAge(Integer age) {
  19. this.age = age;
  20. }
  21. @Override
  22. public String toString() {
  23. return "User{" +
  24. "name='" + name + '\'' +
  25. ", age=" + age +
  26. '}';
  27. }
  28. }

然后在feign-consumer中也创建逾期一样的User类。

然后再HelloService接口中新增上述接口的绑定:

  1. @FeignClient("hello-service")//用于绑定名为hello-service服务
  2. public interface HelloService {
  3. @RequestMapping("/hello")
  4. public String hello();
  5. @RequestMapping(value = "/hello1", method = RequestMethod.GET)
  6. String hello(@RequestParam("name") String name);
  7. @RequestMapping(value = "/hello2", method = RequestMethod.GET)
  8. Map<String,Object> hello(@RequestHeader("name") String name, @RequestHeader("author") String author, @RequestHeader("price") Integer price);
  9. @RequestMapping(value = "/hello3", method = RequestMethod.POST)
  10. String hello(@RequestBody Map<String,Object> book);
  11. @RequestMapping(value = "/hello4", method = RequestMethod.POST)
  12. String hello(@RequestBody User user);
  13. }

这里需要注意在绑定参数时,@RequestParam,@RequestHeader等可以指定参数名称的注解的value参数不能少。在Feign中绑定参数必须通过value来指定具体的参数名不然会抛出IlleglStateException异常,value属性不能为空。

最后控制器新增上述接口:

  1. @RestController
  2. public class ConsumerController {
  3. @Autowired
  4. HelloService helloService;
  5. @GetMapping("/feign-consumer")
  6. public String helloConsumer(){
  7. return helloService.hello();
  8. }
  9. @RequestMapping("/hello1")
  10. public String hello1() {
  11. return helloService.hello("张三");
  12. }
  13. @RequestMapping(value = "/hello2")
  14. public Map<String,Object> hello2() throws UnsupportedEncodingException {
  15. Map<String,Object> book = helloService.hello(URLEncoder.encode("三国演义","UTF-8"), URLEncoder.encode("罗贯中","UTF-8"), 33);
  16. System.out.println(book);
  17. return book;
  18. }
  19. @RequestMapping("/hello3")
  20. public String hello3() {
  21. Map<String,Object> book = new HashMap<String,Object>();
  22. book.put("name","三国演义");
  23. book.put("author","罗贯中");
  24. return helloService.hello(book);
  25. }
  26. @RequestMapping("/hello4")
  27. public String hello4() {
  28. User user=new User("刘德华",99);
  29. return helloService.hello(user);
  30. }
  31. }

70 3

70 4

70 5

70 6

发表评论

表情:
评论列表 (有 0 条评论,272人围观)

还没有评论,来说两句吧...

相关阅读