• 04_feign介绍(OpenFeign)


    feign介绍

    更接口化 面向对象那种形式 (消费端)

    Spring Cloud openfeign对Feign进行了增强,使其支持Spring MVC注解,另外还整合了Rlbbon和Nacos,从而使得Felgn的使用更加方便

    Feign可以做到使用HTTP 请求远程服务时就像调用本地方法一样的体验

    OpenFeign—快速使用

    复制order-nacos项目

    1.引入依赖

       
            <dependency>
                <groupId>org.springframework.cloudgroupId>
                <artifactId>spring-cloud-starter-openfeignartifactId>
            dependency>
        dependencies>
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6

    2.编写接口

    package com.tian.order.feign;
    
    import org.springframework.cloud.openfeign.FeignClient;
    import org.springframework.web.bind.annotation.RequestMapping;
    
    /**
     * name 指定调用rest接口所对应的服务名
     * path指定调用rest接口所在的StockController指定的@RequestMapping
     */
    @FeignClient(name = "stock-service",path = "/stock")
    public interface StockFeignService {
        //声明需要调用的rest接口对应得方法
        //没有实现类 ----  可以联想mybatis 动态代理
        @RequestMapping("/reduct")
         String reduct();
    }
    /*
    *  stock-service controller的代码
    @RestController
    @RequestMapping("/stock")
    public class StockController {
    
        @Value("${server.port}")
        String port;
    
        @RequestMapping("/reduct")
        public String reduct(){
            System.out.println("扣减库存");
            return "扣减库存"+port;
        }
    }
    
    * */
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10
    • 11
    • 12
    • 13
    • 14
    • 15
    • 16
    • 17
    • 18
    • 19
    • 20
    • 21
    • 22
    • 23
    • 24
    • 25
    • 26
    • 27
    • 28
    • 29
    • 30
    • 31
    • 32
    • 33

    3.controller层

    @RestController
    @RequestMapping("/order")
    public class OrderController {
        @Autowired
        StockFeignService stockFeignService;
        @RequestMapping("/add")
        public String add(){
            System.out.println("下单成功!");
            String msg = stockFeignService.reduct();
            return "hello feign"+msg;
        }
    }
    
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10
    • 11
    • 12
    • 13

    4.主启动类

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

    5.配置文件

    server:
      port: 8040
    #应用名称 nacos会将该名称当作服务名称
    spring:
      application:
        name: order-service
      cloud:
        nacos:
          server-addr: 127.0.0.1:8848
          discovery:
            username: nacos
            password: nacos
            namespace: public
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10
    • 11
    • 12
    • 13

    6.测试访问

    http://localhost:8040/order/add

    OpenFeign—日志配置

    通过源码可以看到日志等级有4种,分别是;

    • NONE【性能最佳,适用于生产】:不记录任何日志(默认值)。

    • BASIC【适用于生产环境追踪问题】︰仅记录请求方法、 URL、响应状态代码以及执行时间。

    • HEADERS:记录BASIC级别的基础上,记录请求和响应的header.

    • FULL【比较适用于开发及测试环境定位问题】∶记录请求和响应的header、body和元数据。

    • 全局配置 作用于所有的服务提供方

    1.创建一个模块 product-nacos

    pom依赖

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

    配置文件

    server:
      port: 8023
    
    #应用名称 nacos会将该名称当作服务名称
    spring:
      application:
        name: product-service
      cloud:
        nacos:
          server-addr: 127.0.0.1:8848
          discovery:
            username: nacos
            password: nacos
            namespace: public
    
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10
    • 11
    • 12
    • 13
    • 14
    • 15

    controller

    @RestController
    @RequestMapping("/product")
    public class ProductController {
    
        @Value("${server.port}")
        String port;
    
        @RequestMapping("/{id}")
        public String get(@PathVariable Integer id){
            System.out.println("查询商品"+id);
            return "查询商品"+id+":"+port;
        }
    }
    
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10
    • 11
    • 12
    • 13
    • 14

    2.order-openfeign模块

    编写配置类 config/FeignConfig.java

    //@Configuration
    //如果想要局部 注释@Configuration 想在哪配置日记就加上
    //例在StockFeignService接口中配置 @FeignClient(name = "stock-service",path = "/stock",configuration = FeignConfig.class)
    public class FeignConfig {
    
        @Bean
        public Logger.Level feignLoggerLevel(){
            return Logger.Level.FULL;
        }
    }
    
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10
    • 11

    相当于serive层 feign/StockFeignService

    /**
     * name 指定调用rest接口所对应的服务名
     * path指定调用rest接口所在的StockController指定的@RequestMapping
     */
    @FeignClient(name = "stock-service",path = "/stock",configuration = FeignConfig.class)
    public interface StockFeignService {
        //声明需要调用的rest接口对应得方法
        //没有实现类 ----  可以联想mybatis 动态代理
        @RequestMapping("/reduct")
         String reduct();
    }
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10
    • 11

    相当于serive层 feign/ProductFeignService

    @FeignClient(name = "product-service",path = "/product")
    public interface ProductFeignService {
        //feign更严格 @PathVariable("id") 要指定参数
        @RequestMapping("/{id}")
        public String get(@PathVariable("id") Integer id);
    }
    
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7

    配置文件配置局部日志

    server:
      port: 8040
    #应用名称 nacos会将该名称当作服务名称
    spring:
      application:
        name: product-service
      cloud:
        nacos:
          server-addr: 127.0.0.1:8848
          discovery:
            username: nacos
            password: nacos
            namespace: public
    #全局配置--springboot默认的日记级别是info ,feign的debug日志级别就不会输入
    logging:
      level:   # 如果在这写上debug 就是所有的 非常多
        com.tian.order.feign: debug   
    #局部配置 -- feign日记局部配置
    feign:
      client:
        config:
          product-service:
            loggerLevel: BASIC
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10
    • 11
    • 12
    • 13
    • 14
    • 15
    • 16
    • 17
    • 18
    • 19
    • 20
    • 21
    • 22
    • 23

    controller层

    @RestController
    @RequestMapping("/order")
    public class OrderController {
        @Autowired
        StockFeignService stockFeignService;
        @Autowired
        ProductFeignService productFeignService;
    
    
        @RequestMapping("/add")
        public String add(){
            System.out.println("下单成功!");
            String msg = stockFeignService.reduct();
            String s = productFeignService.get(1);
            return "hello feign"+msg+s;
        }
    }
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10
    • 11
    • 12
    • 13
    • 14
    • 15
    • 16
    • 17

    测试访问查看控制台日记记录

    http://localhost:8040/order/add

    结果页面显示 hello feign扣减库存8021查询商品1:8023

    • 局部配置

    1.配置类 2.配置文件

    配置类

    @FeignClient(name = "stock-service",path = "/stock",configuration = FeignConfig.class)
    public interface StockFeignService {
        //...
    }
    
    • 1
    • 2
    • 3
    • 4

    配置文件

    #局部配置 -- feign日记局部配置
    feign:
      client:
        config:
          product-service:   #提供服务名
            loggerLevel: BASIC
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6

    OpenFeign—契约配置

    @RequestMapping("/{id}")  //原生注解@RequestLine
    public String get(@PathVariable("id") Integer id); //原生注解@Param
    
    • 1
    • 2

    使用场景 版本升级 保留这个原生注解

    Sping Cloud在Feign的基础上做了扩展,使目 spring MNVC的注解来完feign的功能。而生的feign是不支持springMVC注解的,如果你想在springcloud中使用质生的主解方式来定义容户端也是可以的的,通过配置契约来改变这个配置,Spring Cloud 中默认的是 SpringMvcContract。

    ​ Spring Cloud 1早期版本就是用的原生Fegin.随着netflix的停更替换成了Open feign

    1.配置类配置

       /**
         * 修改契约配置,支持feign原生的注解
         * @return
         */
        @Bean
        public Contract feignContract(){
            return new Contract.Default();
        }
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8

    2.配置文件配置

    # feign日记局部配置
    feign:
      client:
        config:
          product-service:
            loggerLevel: BASIC
            contract: feign.Contract.Default #设置为默认的契约(还原成原生注解)
    
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8

    ProductFeignService接口改变

    @FeignClient(name = "product-service",path = "/product")
    public interface ProductFeignService {
        @RequestLine("GET /{id}") 
        public String get(@Param("id") Integer id); /
    }
    
    • 1
    • 2
    • 3
    • 4
    • 5

    OpenFeign—超时时间配置

    通过Oplons 可以配置连接超时时间和读取超的间,Options 的第一个参数是连接的超的时时间(ms),默认值是2s;第二个是清求处理的超时加时间(ns),默认值是5s.

    全局配置

    @Configuration
    public class FeignConfig {
        @Bean
        public Request.Options options(){
            return new Request.Options(5000,10000);
        }
    }
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7

    yml中配置

    # feign日记局部配置
    feign:
      client:
        config:
          product-service:
            loggerLevel: BASIC
            contract: feign.Contract.Default #设置为默认的契约(还原成原生注解)
            # 连接超时时间 默认2s
            connectTimeout: 5000
            # 请求处理超时时间 默认5s
            readTimeout: 3000
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10
    • 11

    OpenFeign—自定义拦截器

    1.编写拦截器

    package com.tian.order.interceptor;
    
    import feign.RequestInterceptor;
    import feign.RequestTemplate;
    import org.slf4j.Logger;
    import org.slf4j.LoggerFactory;
    
    public class CustomFeignInterceptor implements RequestInterceptor {
       Logger logger= LoggerFactory.getLogger(this.getClass());
        public void apply(RequestTemplate requestTemplate) {
            requestTemplate.header("xxx","xxx");
            requestTemplate.query("id","111");
            requestTemplate.uri("9");
            logger.info("feign拦截器!");
        }
    }
    
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10
    • 11
    • 12
    • 13
    • 14
    • 15
    • 16
    • 17

    2.配置文件使其生效(或者注入配置类 configuration 中@Bean)

    # feign日记局部配置
    feign:
      client:
        config:
          product-service:
            loggerLevel: BASIC
            contract: feign.Contract.Default #设置为默认的契约(还原成原生注解)
            # 连接超时时间 默认2s
    #        connectTimeout: 5000
            # 请求处理超时时间 默认5s
    #        readTimeout: 3000
            requestInterceptors[0]:
              com.tian.order.interceptor.CustomFeignInterceptor
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10
    • 11
    • 12
    • 13

    3.测试请求

    localhost:8040/order/add
    发现控制台输出 feign拦截器! 页面显示 9
    常用于日记 授权等

  • 相关阅读:
    RocketMQ 源码一,启动篇
    adb调试Linux嵌入式设备记录
    springboot基于微信小程序的电器商城系统的设计与实现毕业设计源码251453
    5分钟快速上手 pytest 测试框架
    [MapStruct]如何获取Mapper
    外包干了四年,人直接废了。。。
    一次分表的技术方案分享
    二叉树(上)
    用Java使用API接口获取Lazada商品详情
    2022亚太赛题浅评
  • 原文地址:https://blog.csdn.net/xixihaha_coder/article/details/126620849