• SpringCloud之OpenFeign调用解读


    目录

    基本介绍

    引进

    OpenFeign概述

    OpenFeign作用 

    @FeignClient 

    @EnableFeignClients 

    Java代码实战

    实战架构

    父工程pom文件 

    teacher-service服务

    student-service服务

    测试

    自定义配置


    基本介绍

    引进

    如果我们利用RestTemplate发起远程调用的代码时会存在一些问题比如:

    •代码可读性差,编程体验不统一

    •参数复杂URL难以维护

    1. String url="http://teacherservice/getTeacher";
    2. Teacher teacher = restTemplate.getForObject(url, Teacher.class);

    OpenFeign概述

    OpenFeign是一个显示声明式的WebService客户端。使用OpenFeign能让编写Web Service客户端更加简单。使用时只需定义服务接口,然后在上面添加注解。OpenFeign也支持可拔插式的编码和解码器。spring cloud对feign进行了封装,使其支持MVC注解和HttpMessageConverts。和eureka(服务注册中心)和ribbon组合可以实现负载均衡。

    在Spring Cloud中使用OpenFeign,可以做到使用HTTP请求访问远程服务,就像调用本地方法一样的,开发者完全感知不到这是在调用远程方法,更感知不到在访问HTTP请求,非常的方便。

    cloud官网介绍Feign:Spring Cloud OpenFeign

    OpenFeign源码:GitHub - OpenFeign/feign: Feign makes writing java http clients easier

    OpenFeign作用 

    • OpenFeign的设计宗旨式简化Java Http客户端的开发。Feign在restTemplate的基础上做了进一步的封装,由其来帮助我们定义和实现依赖服务接口的定义。在OpenFeign的协助下,我们只需创建一个接口并使用注解的方式进行配置(类似于Dao接口上面的Mapper注解)即可完成对服务提供方的接口绑定,大大简化了Spring cloud Ribbon的开发,自动封装服务调用客户端的开发量。
    • OpenFeign集成了Ribbon,利用ribbon维护了服务列表,并且通过ribbon实现了客户端的负载均衡。与ribbon不同的是,通过OpenFeign只需要定义服务绑定接口且以申明式的方法,优雅而简单的实现了服务调用。

    @FeignClient 

    @FeignClient 实现的是声明式的、模块化的Http客户端,可以让我们对其他服务接口的访问更边界就像是controller和service之间的调用一样。

    @FeignClient属性如下:

    • name:指定该类的容器名称,类似于@Service(容器名称)
    • url: url一般用于调试,可以手动指定@FeignClient调用的地址
    • decode404:当发生http 404错误时,如果该字段位true,会调用decoder进行解码,否则抛出FeignException
    •  configuration: Feign配置类,可以自定义Feign的Encoder、Decoder、LogLevel、Contract
    •  fallback: 定义容错的处理类,当调用远程接口失败或超时时,会调用对应接口的容错逻辑,fallback指定的类必须实现@FeignClient标记的接口
    • fallbackFactory: 工厂类,用于生成fallback类示例,通过这个属性我们可以实现每个接口通用的容错逻辑,减少重复的代码
    • path: 定义当前FeignClient的统一前缀,当我们项目中配置了server.context-path,server.servlet-path时使用
    1. @FeignClient(name="teacherservice")
    2. public interface TeacherServiceFeign {
    3. @GetMapping("/getTeacher/{id}")
    4. Teacher getInfo(@PathVariable("id") String id);
    5. }

    @EnableFeignClients 

    在的启动类添加​ @EnableFeignClients注解开启Feign的功能  

    用注解@EnableFeignClients启用feign客户端;扫描和注册feign客户端bean定义

    @EnableFeignClients注解中的basePackges属性中是一个数组,可以填写多个值,其主要作用是指定当前模块中需要用到那些地址下的feign接口,起到一个discovery发现feign接口的作用。

    Java代码实战

    实战架构

    俩个为俩个不同的端口的service端,客户端向8002端口的studentservice发送一个请求(/getInfo/{id})以后,8002端口的studentservice需要往teacherservice发送一个请求(/getTeacher/{id})返回数据。

    父工程pom文件 

    统一管理版本信息 

    1. <groupId>org.examplegroupId>
    2. <artifactId>eurek-testartifactId>
    3. <version>1.0-SNAPSHOTversion>
    4. <modules>
    5. <module>eurek-servemodule>
    6. <module>student-servicemodule>
    7. <module>teacher-servicemodule>
    8. modules>
    9. <packaging>pompackaging>
    10. <parent>
    11. <groupId>org.springframework.bootgroupId>
    12. <artifactId>spring-boot-starter-parentartifactId>
    13. <version>2.3.12.RELEASEversion>
    14. <relativePath/>
    15. parent>
    16. <properties>
    17. <project.build.sourceEncoding>UTF-8project.build.sourceEncoding>
    18. <project.reporting.outputEncoding>UTF-8project.reporting.outputEncoding>
    19. <java.version>1.8java.version>
    20. <spring-cloud.version>Hoxton.SR10spring-cloud.version>
    21. <mysql.version>5.1.47mysql.version>
    22. <mybatis.version>2.1.1mybatis.version>
    23. properties>
    24. <dependencyManagement>
    25. <dependencies>
    26. <dependency>
    27. <groupId>org.springframework.cloudgroupId>
    28. <artifactId>spring-cloud-dependenciesartifactId>
    29. <version>${spring-cloud.version}version>
    30. <type>pomtype>
    31. <scope>importscope>
    32. dependency>
    33. <dependency>
    34. <groupId>com.alibaba.cloudgroupId>
    35. <artifactId>spring-cloud-alibaba-dependenciesartifactId>
    36. <version>2.2.5.RELEASEversion>
    37. <type>pomtype>
    38. <scope>importscope>
    39. dependency>
    40. dependencies>
    41. dependencyManagement>
    42. <dependencies>
    43. <dependency>
    44. <groupId>org.projectlombokgroupId>
    45. <artifactId>lombokartifactId>
    46. dependency>
    47. dependencies>

    teacher-service服务

     pom文件

    1. <dependencies>
    2. <dependency>
    3. <groupId>org.springframework.bootgroupId>
    4. <artifactId>spring-boot-starter-webartifactId>
    5. dependency>
    6. <dependency>
    7. <groupId>com.alibaba.cloudgroupId>
    8. <artifactId>spring-cloud-starter-alibaba-nacos-discoveryartifactId>
    9. dependency>
    10. dependencies>

    启动类

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

    yml配置文件 

    1. server:
    2. port: 8002
    3. spring:
    4. application:
    5. name: teacherservice
    6. cloud:
    7. nacos:
    8. server-addr: localhost:8848

     Teacher类

    1. @Data
    2. @AllArgsConstructor
    3. @NoArgsConstructor
    4. public class Teacher implements Serializable {
    5. private String name;
    6. private String sex;
    7. }

    TeachertController

    1. @RestController
    2. public class TeacherController {
    3. @GetMapping("/getTeacher/{id}")
    4. public Teacher getInfo(@PathVariable("id") String id){
    5. return new Teacher("张三-"+id,"男");
    6. }
    7. }

    student-service服务

    pom文件

    1. <dependencies>
    2. <dependency>
    3. <groupId>org.springframework.bootgroupId>
    4. <artifactId>spring-boot-starter-webartifactId>
    5. dependency>
    6. <dependency>
    7. <groupId>com.alibaba.cloudgroupId>
    8. <artifactId>spring-cloud-starter-alibaba-nacos-discoveryartifactId>
    9. dependency>
    10. <dependency>
    11. <groupId>org.springframework.cloudgroupId>
    12. <artifactId>spring-cloud-starter-openfeignartifactId>
    13. dependency>
    14. dependencies>

    yml配置文件 

    1. server:
    2. port: 8002
    3. spring:
    4. application:
    5. name: studentservice
    6. cloud:
    7. nacos:
    8. server-addr: localhost:8848

     启动类 

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

     Teacher类

    1. @Data
    2. @AllArgsConstructor
    3. @NoArgsConstructor
    4. public class Teacher implements Serializable {
    5. private String name;
    6. private String sex;
    7. }

    TeacherServiceFeign ​ 

    1. @FeignClient("teacherservice")
    2. public interface TeacherServiceFeign {
    3. @GetMapping("/getTeacher/{id}")
    4. Teacher getInfo(@PathVariable("id") String id);
    5. }

    个客户端主要是基于SpringMVC的注解来声明远程调用的信息,比如:

    • 服务名称:teacherservice

    • 请求方式:GET

    • 请求路径:/getTeacher/{id}

    • 请求参数:String id

    • 返回值类型:Teacher

    这样,Feign就可以帮助我们发送http请求,无需自己使用RestTemplate来发送了。

     StudentController

    1. @RestController
    2. public class StudentController implements Serializable {
    3. @Autowired
    4. TeacherServiceFeign teacherServiceFeign;
    5. @GetMapping("/getInfo")
    6. public Teacher getInfo(){
    7. Teacher teacher = teacherServiceFeign.getInfo("111");
    8. return teacher;
    9. }
    10. }

    测试

    GET http://localhost:8002/getInfo

    HTTP/1.1 200 
    Content-Type: application/json
    Transfer-Encoding: chunked
    Date: Tue, 17 Oct 2023 02:46:43 GMT
    Keep-Alive: timeout=60
    Connection: keep-alive

    {
      "name": "张三-111",
      "sex": "男"
    }

    自定义配置

    Feign可以支持很多的自定义配置,如下表所示:

    类型作用说明
    feign.Logger.Level修改日志级别包含四种不同的级别:NONE、BASIC、HEADERS、FULL
    feign.codec.Decoder响应结果的解析器http远程调用的结果做解析,例如解析json字符串为java对象
    feign.codec.Encoder请求参数编码将请求参数编码,便于通过http请求发送
    feign. Contract支持的注解格式默认是SpringMVC的注解
    feign. Retryer失败重试机制请求失败的重试机制,默认是没有,不过会使用Ribbon的重试

    一般情况下,默认值就能满足我们使用,如果要自定义时,只需要创建自定义的@Bean覆盖默认Bean即可。

  • 相关阅读:
    [HD2006.X1] 打印图形(菱形换壳)——海淀区赛
    浏览器输入框或表单关闭自动填充autocomplete=off
    IDEA社区版(Community Edition)创建Springboot-Web项目,Java
    Java注解最全详解(超级详细)
    Redis快速入门
    新技术前沿-2023-基于Stable Difussion体验AI绘画
    2024年山东省职业院校技能大赛中职组“网络安全”赛项竞赛试题-B
    JAVA【设计模式】装饰器模式
    JAVA艾灸减肥管理网站计算机毕业设计Mybatis+系统+数据库+调试部署
    智能制造时代下,MES管理系统需要解决哪些问题
  • 原文地址:https://blog.csdn.net/m0_62436868/article/details/133879073