zoukankan      html  css  js  c++  java
  • springcloud组件梳理之Feign

        最近刚好打算给公司刚毕业的新同事做一个springcloud系列的培训,趁此机会刚好梳理下springcloud常用组件的使用,今天先对feign做个简单介绍!

        feign是一个声明式的Web服务客户端,它使得发送web请求变得很容易,而openFign是springcloud对feign的一个升级,可以支持springMvc的注解;

        接下来描述下我是怎么使用openFeign发送web请求的,首先需要明确,使用openFeign是有一定的代码侵入的,不过侵入的是consumer的代码,通过在consumer中添加openFeign的注解来拼装请求并发送,

    一般有两种方式,一种是consumer端根据provider提供的接口文档编写调用用例.另一种是由Prodiver提供一个接口API的jar包供consumer调用;下面上我的测试步骤及代码,两种方式都有涉及;

        consumer端

     首先在consumer中引入openFeigin以及HTTPClient的依赖:

         <!-- 引入open-feign的依赖 -->
            <dependency>
               <groupId>org.springframework.cloud</groupId>
               <artifactId>spring-cloud-starter-openfeign</artifactId>
            </dependency>
    
            <!-- 引入open-feign的httpClien依赖 -->
            <dependency>
               <groupId>io.github.openfeign</groupId>
               <artifactId>feign-httpclient</artifactId>
            </dependency>
         <!-- 引入Prodiver提供的接口包(根据实际需要) -->
         <dependency>
            <groupId>com.darling.api</groupId>
            <artifactId>server-apis</artifactId>
            <version>0.0.1-SNAPSHOT</version>
            <scope>compile</scope>
         </dependency>

      然后在consumer中封装一个service引入feign,来进行远程调用,关键代码如下:

    package com.darling.eureka.consumer.service;
    
    import com.darling.api.service.UserService;
    import com.darling.eureka.consumer.model.User;
    import org.springframework.cloud.openfeign.FeignClient;
    import org.springframework.web.bind.annotation.*;
    
    /**
     * @description:  通过openFeign远程调用服务提供者
     * @author: dll
     * @date: Created in 2021/9/14 12:29
     * @version: 1.0
     * @modified By:
     */
    @FeignClient(name = "EUREKA-PROVIDER")
    public interface UserApiService extends UserService{
    
        @GetMapping("/test/sayHi?name={name}")
        String sayHi(@PathVariable String name);
    
        /**
         * 测试 插入一条信息
         * @param user
         * @return
         */
        @GetMapping("/test/insertInfo")
        String insertInfo(@RequestBody User user);
    
    }

      说明:

        1、consumer中的启动类需要加上@EnableFeignClients注解,这里代码没有贴出

        2、FeignClient注解有多种属性可选,如自定义配置信息的configuration、直接指定访问链接的url等,由于我这里只是一个测试的demo就直接用name来指定在eureka中注册的Prodiver的服务名称了;

        3、代码中的GetMapping就是上面说的两种方式之一,consumer根据Prodiver提供的接口文档进行编码调用的;

        4、代码中的UserService就是上面说的另一种方式,由服务提供者提供的一个接口依赖包,我这里包名叫server-apis,,这样consumer中就可以像调用本地方法一样调用远程服务提供的接口能力,下面贴上UserService的代码:

    package com.darling.api.service;
    
    import com.darling.api.model.UserInfo;
    import org.springframework.web.bind.annotation.GetMapping;
    import org.springframework.web.bind.annotation.RequestMapping;
    
    /**
     * @description:
     * @author: dll
     * @date: Created in 2021/9/15 22:02
     * @version:
     * @modified By:
     */
    @RequestMapping("/serverApis")
    public interface UserService {
    
        @GetMapping("/test")
        UserInfo test();
    
        /**
         * 获取用户信息
         * @return  用户姓名、年龄等信息
         */
        @GetMapping("/getInfo")
        UserInfo getInfo();
    
    }

        需要注意的是,无论是通过Prodiver提供的依赖包还是直接编写调用代码,以上代码中所有的类似GetMapping、PostMapping的注解都是由Prodiver暴露出来的接口请求路径,由feign负责识别、拼装并发起远程请求的;

        下面来看看consumer中的Controller的调用代码:

    package com.darling.eureka.consumer.controller;
    
    import com.darling.api.model.UserInfo;
    import com.darling.eureka.consumer.model.User;
    import com.darling.eureka.consumer.service.UserApiService;
    import org.springframework.web.bind.annotation.RequestMapping;
    import org.springframework.web.bind.annotation.RestController;
    
    import javax.annotation.Resource;
    
    /**
     * @description: 测试openFeign的远程调用
     * @author: dll
     * @date: Created in 2021/8/25 21:52
     * @version: 1.0
     * @modified By:
     */
    @RestController
    @RequestMapping("/consumer/test")
    public class TestConsumerController {
    
        @Resource
        private UserApiService userApiService;
    
        /**
         * 调用UserApiService中自己根据接口文档编写的调用代码
         * @return
         */
        @RequestMapping("/sayHello")
        public String sayHello() {
            String res = userApiService.sayHi("hahaha");
            System.out.println("res = " + res);
            return res;
        }
    
        /**
         * 调用UserApiService中自己根据接口文档编写的调用代码
         * @param user
         * @return
         */
        @RequestMapping("/insert")
        public String insertInfo(User user) {
            String res = userApiService.insertInfo(user);
            System.out.println("res = " + res);
            return res;
        }
    
        /**
         * 调用UserApiService中由Prodiver提供的server-apis依赖包中的UserService的接口
         * @return
         */
        @RequestMapping("/getUserInfo")
        public UserInfo getUserInfo() {
            UserInfo res = userApiService.getInfo();
            System.out.println("res = " + res);
            return res;
        }
    
    }

      provider端

      如果没有采用由Prodiver提供接口依赖包的方式的话,使用openFeign对Prodiver端几乎无任何侵入,Prodiver只需写好自己可以提供的服务并提供一份接口文档即可;

      下面主要聊聊如果通过提供接口依赖包的方式Prodiver应该做哪些调整以及其中可能遇到的坑

      首先,需要定义一个专门用来提供接口能力的api服务(server-apis),就正常的web服务即可,代码可参见上面的UserService;然后由Prodiver引入这个服务;需要注意的是如果通过这种方式提供服务的话,Prodiver

    需要以接口实现类的方式来提供具体服务的实现,不能在controller中定义接口的调用路径了,否则访问会直接404;

      总结

      通过以上的调用实例,我们可以得出结论,feign调用虽香但是对代码的确会有一定的侵入性,主要针对服务的调用者而言,而是通过依赖包调用还是由consumer自己编码调用,无非是愿意接受jar包耦合还是接口文档耦合了,

    所以对于同一个团队开发的consumer和Prodiver来说,个人更倾向于通过定义统一的接口依赖包,双方严格按照依赖包进行开发,依赖包的变更大家都能实时感知并作出及时响应,调用起来也更方便;而对于跨团队来开发consumer

    和Prodiver来说,个人认为通过接口文档会更合理,consumer相对来说能把命运掌握在自己手上,对接的时候只认接口文档,减少了对接口包的依赖

      

        

       

    希望每get一个知识点都能坚持用博客记录下来,加油!
  • 相关阅读:
    程序员的最大挑战
    12个有效的提高编程技能的方法
    风雨20年:我所积累的20条编程经验
    java的继承机制
    Java中获得程序当前路径的4中方法
    关于String的hashCode
    使用三目运算符时注意的一个问题
    linux查找符合条件的文件并删除
    Tomcat性能优化及JVM内存工作原理
    Linux(Centos)下调整分区大小(以home和根分区为例)
  • 原文地址:https://www.cnblogs.com/darling2047/p/15308234.html
Copyright © 2011-2022 走看看