SpringCloud中的OpenFeign调用解读

 更新时间:2023年11月03日 10:36:30   作者:一个风轻云淡  
OpenFeign是一个显示声明式的WebService客户端,使用OpenFeign能让编写Web Service客户端更加简单OpenFeign的设计宗旨式简化Java Http客户端的开发,本文给大家介绍SpringCloud之OpenFeign调用解读,感兴趣的朋友一起看看吧

基本介绍

引进

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

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

•参数复杂URL难以维护

String url="http://teacherservice/getTeacher";
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时使用
@FeignClient(name="teacherservice")
public interface TeacherServiceFeign {
    @GetMapping("/getTeacher/{id}")
    Teacher getInfo(@PathVariable("id") String id);
}

@EnableFeignClients 

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

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

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

Java代码实战

实战架构

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

父工程pom文件 

统一管理版本信息 

    <groupId>org.example</groupId>
    <artifactId>eurek-test</artifactId>
    <version>1.0-SNAPSHOT</version>
    <modules>
        <module>eurek-serve</module>
        <module>student-service</module>
        <module>teacher-service</module>
    </modules>
    <packaging>pom</packaging>
    <parent>
        <groupId>org.springframework.boot</groupId>
        <artifactId>spring-boot-starter-parent</artifactId>
        <version>2.3.12.RELEASE</version>
        <relativePath/>
    </parent>
    <properties>
        <project.build.sourceEncoding>UTF-8</project.build.sourceEncoding>
        <project.reporting.outputEncoding>UTF-8</project.reporting.outputEncoding>
        <java.version>1.8</java.version>
        <spring-cloud.version>Hoxton.SR10</spring-cloud.version>
        <mysql.version>5.1.47</mysql.version>
        <mybatis.version>2.1.1</mybatis.version>
    </properties>
    <dependencyManagement>
        <dependencies>
            <!-- springCloud -->
            <dependency>
                <groupId>org.springframework.cloud</groupId>
                <artifactId>spring-cloud-dependencies</artifactId>
                <version>${spring-cloud.version}</version>
                <type>pom</type>
                <scope>import</scope>
            </dependency>
            <!--nacos的管理依赖-->
            <dependency>
                <groupId>com.alibaba.cloud</groupId>
                <artifactId>spring-cloud-alibaba-dependencies</artifactId>
                <version>2.2.5.RELEASE</version>
                <type>pom</type>
                <scope>import</scope>
            </dependency>
        </dependencies>
    </dependencyManagement>
    <dependencies>
        <dependency>
            <groupId>org.projectlombok</groupId>
            <artifactId>lombok</artifactId>
        </dependency>
    </dependencies>

teacher-service服务

 pom文件

   <dependencies>
       <dependency>
           <groupId>org.springframework.boot</groupId>
           <artifactId>spring-boot-starter-web</artifactId>
       </dependency>
       <!-- nacos客户端依赖包 -->
       <dependency>
           <groupId>com.alibaba.cloud</groupId>
           <artifactId>spring-cloud-starter-alibaba-nacos-discovery</artifactId>
       </dependency>
   </dependencies>

启动类

@SpringBootApplication
public class TeacherApplication {
    public static void main(String[] args) {
        SpringApplication.run(TeacherApplication.class,args);
    }
}

yml配置文件 

server:
  port: 8002
spring:
  application:
    name: teacherservice
  cloud:
    nacos:
      server-addr: localhost:8848

 Teacher类

@Data
@AllArgsConstructor
@NoArgsConstructor
public class Teacher implements Serializable {
    private  String name;
    private  String sex;
}

TeachertController

@RestController
public class TeacherController {
    @GetMapping("/getTeacher/{id}")
    public Teacher getInfo(@PathVariable("id") String id){
        return new Teacher("张三-"+id,"男");
    }
}

student-service服务

pom文件

   <dependencies>
       <dependency>
           <groupId>org.springframework.boot</groupId>
           <artifactId>spring-boot-starter-web</artifactId>
       </dependency>
       <!-- nacos客户端依赖包 -->
       <dependency>
           <groupId>com.alibaba.cloud</groupId>
           <artifactId>spring-cloud-starter-alibaba-nacos-discovery</artifactId>
       </dependency>
       <dependency>
           <groupId>org.springframework.cloud</groupId>
           <artifactId>spring-cloud-starter-openfeign</artifactId>
       </dependency>
   </dependencies>

yml配置文件 

server:
  port: 8002
spring:
  application:
    name: studentservice
  cloud:
    nacos:
      server-addr: localhost:8848

 启动类 

@SpringBootApplication
@EnableFeignClients
public class StudentApplication {
    public static void main(String[] args) {
        SpringApplication.run(StudentApplication.class,args);
    }
}

 Teacher类

@Data
@AllArgsConstructor
@NoArgsConstructor
public class Teacher implements Serializable {
    private  String name;
    private  String sex;
}

TeacherServiceFeign ​ 

@FeignClient("teacherservice")
public interface TeacherServiceFeign {
    @GetMapping("/getTeacher/{id}")
    Teacher getInfo(@PathVariable("id") String id);
}

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

  • 服务名称:teacherservice
  • 请求方式:GET
  • 请求路径:/getTeacher/{id}
  • 请求参数:String id
  • 返回值类型:Teacher

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

 StudentController

@RestController
public class StudentController implements Serializable {
    @Autowired
    TeacherServiceFeign teacherServiceFeign;
    @GetMapping("/getInfo")
    public Teacher getInfo(){
        Teacher teacher = teacherServiceFeign.getInfo("111");
        return teacher;
    }
}

测试

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即可。

到此这篇关于SpringCloud之OpenFeign调用解读的文章就介绍到这了,更多相关SpringCloud OpenFeign调用解读内容请搜索脚本之家以前的文章或继续浏览下面的相关文章希望大家以后多多支持脚本之家!

相关文章

  • 源码解读Spring-Integration执行过程

    源码解读Spring-Integration执行过程

    Spring-Integration基于Spring,在应用程序中启用了轻量级消息传递,并支持通过声明式适配器与外部系统集成,今天主要是看个简单的hello word进来分析下整个执行过程,感兴趣的朋友一起看看吧
    2021-06-06
  • Springboot实现连接多个ElasticSearch数据库的过程

    Springboot实现连接多个ElasticSearch数据库的过程

    这篇文章介绍了如何在Springboot项目中实现与多个Elasticsearch数据库的高效交互,本文结合实例代码给大家介绍的非常详细,感兴趣的朋友跟随小编一起看看吧
    2026-03-03
  • Java截取字符串的几种方法示例

    Java截取字符串的几种方法示例

    众所周知java提供了很多字符串截取的方式,下面这篇文章主要给大家总结介绍了关于Java截取字符串的几种方法,文中通过实例代码介绍的非常详细,需要的朋友可以参考下
    2023-04-04
  • 解决MyEclipse10.7部署报错抛空指针异常问题的方法

    解决MyEclipse10.7部署报错抛空指针异常问题的方法

    这篇文章主要介绍了解决MyEclipse10.7部署报错抛空指针异常问题的方法,需要的朋友可以参考下
    2015-12-12
  • Spring Data JPA实现数据持久化过程详解

    Spring Data JPA实现数据持久化过程详解

    Spring Data JPA是一个流行的Java持久化框架,它在Java应用程序中提供了一种简单、一致和易于使用的方式来访问各种数据库。本文将介绍Spring Data JPA的基本概念和用法并提供一个完整的实例,帮助您更好地理解它的使用方法和优势
    2023-05-05
  • 使用Filter过滤器中访问getSession()要转化

    使用Filter过滤器中访问getSession()要转化

    这篇文章主要介绍了使用Filter过滤器中访问getSession()要转化,具有很好的参考价值,希望对大家有所帮助。如有错误或未考虑完全的地方,望不吝赐教
    2022-01-01
  • SpringBoot Jpa 自定义查询实现代码详解

    SpringBoot Jpa 自定义查询实现代码详解

    这篇文章主要介绍了SpringBoot Jpa 自定义查询实现代码详解,文中通过示例代码介绍的非常详细,对大家的学习或者工作具有一定的参考学习价值,需要的朋友可以参考下
    2020-02-02
  • Java的信号量semaphore讲解

    Java的信号量semaphore讲解

    这篇文章主要介绍了Java的信号量semaphore讲解,Semaphore底层是基于AbstractQueuedSynchronizer来实现的,Semaphore称为计数信号量,它允许n个任务同时访问某个资源,需要的朋友可以参考下
    2023-12-12
  • vue+springboot+webtrc+websocket实现双人音视频通话会议(最新推荐)

    vue+springboot+webtrc+websocket实现双人音视频通话会议(最新推荐)

    这篇文章主要介绍了vue+springboot+webtrc+websocket实现双人音视频通话会议,本文给大家介绍的非常详细,对大家的学习或工作具有一定的参考借鉴价值,需要的朋友参考下吧
    2025-05-05
  • Mybatis返回插入的主键问题解决方案

    Mybatis返回插入的主键问题解决方案

    这篇文章主要介绍了Mybatis返回插入的主键问题解决方案,文中通过示例代码介绍的非常详细,对大家的学习或者工作具有一定的参考学习价值,需要的朋友可以参考下
    2020-09-09

最新评论