SpringCloud之Feign

1. Feign

1.1 1. Feign 概念


Feign是声明式Web Service客户端,它让微服务之间的调用变得更简单,类似controller调用service。
SpringCloud继承了RibbonEureka,可以使用Feign提供负载均衡的http客户端

只需要创建一个接口,然后添加注册即可~

Feign,主要是社区版,大家都习惯面向接口编程。这个是很多开发人员的规范。调用微服务访问两种方法

  1. 微服务名字【Ribbon
  2. 接口和注解【Feign

1.2 Feign 的作用


  • Feign 旨在使编写Java Http 客户端变得更容易
  • 前面在使用Ribbon + RestTemplate 时,利用RestTemplate 形成了一套模板化的调用方法。但是在实际开发中,由于对服务依赖的调用可能不止一处,往往一个接口会被多出调用,所以通常都会针对每个微服务自行封装一个客户端类来包装这些依赖服务的调用。所以,Feign 在此基础上做了进一步的封装,由它来帮助我们定义和实现依赖服务接口的定义,在Feign的实现下, 我们只需要创建一个接口并使用注解的方式类配置它(类似以前Dao接口上标注Mapper注解,现在是一个微服务接口上面标注一个Feign注解),即可完成对服务提供方的接口绑定,简化了使用Spring Cloud Ribbon 时,自动封装服务调用客户端的开发量。

Feign默认继承了Ribbon

  • 利用Ribbon 维护了MicroServiceCloud-Dept的服务列表信息,并且通过轮询实现了客户端的负载均衡,而与Ribbon 不同的是,通过Feign 只需要定义服务绑定接口且以声明式的方法,优雅而简单的实现了服务调用。

2. Feign的使用步骤


  1. 创建springcloud-consumer-fdept-feign模块

    在这里插入图片描述
    拷贝springcloud-consumer-dept-80模块下的pom.xml,resource,以及java代码到springcoud-consumer-feign模块,并添加feign依赖。

    <!--Feign的依赖-->
    <dependency>
        <groupId>org.springframework.cloud</groupId>
        <artifactId>spring-cloud-starter-feign</artifactId>
        <version>1.4.6.RELEASE</version>
    </dependency>
    

    通过Ribbon 实现: - 原来的controller:DeptConsumberController.java

    @RestController
    public class DeptConsumerController {
    
        /**
         * 理解:消费者,不应该有service层~
         * RestTemplate .... 供我们直接调用就可以了! 注册到Spring中
         * (地址:url, 实体:Map ,Class<T> responseType)
         * <p>
         * 提供多种便捷访问远程http服务的方法,简单的Restful服务模板~
         */
        @Autowired
        private RestTemplate restTemplate;
    
        /**
         * 服务提供方地址前缀
         * <p>
         * Ribbon:我们这里的地址,应该是一个变量,通过服务名来访问
         */
    //    private static final String REST_URL_PREFIX = "http://localhost:8001";
        private static final String REST_URL_PREFIX = "http://SPRINGCLOUD-PROVIDER-DEPT";
    
        /**
         * 消费方添加部门信息
         * @param dept
         * @return
         */
        @RequestMapping("/consumer/dept/add")
        public boolean add(Dept dept) {
            // postForObject(服务提供方地址(接口),参数实体,返回类型.class)
            return restTemplate.postForObject(REST_URL_PREFIX + "/dept/add", dept, Boolean.class);
        }
    
        /**
         * 消费方根据id查询部门信息
         * @param id
         * @return
         */
        @RequestMapping("/consumer/dept/get/{id}")
        public Dept get(@PathVariable("id") Long id) {
            // getForObject(服务提供方地址(接口),返回类型.class)
            return restTemplate.getForObject(REST_URL_PREFIX + "/dept/get/" + id, Dept.class);
        }
    
        /**
         * 消费方查询部门信息列表
         * @return
         */
        @RequestMapping("/consumer/dept/list")
        public List<Dept> list() {
            return restTemplate.getForObject(REST_URL_PREFIX + "/dept/list", List.class);
        }
    }
    

    通过Feign 实现: - 改造后的controller:DeptConsumerController.java

    @RestController
    public class DeptConsumerController {
    
        @Autowired
        private DeptClientService deptClientService;
    
        /**
         * 消费方添加部门信息
         * @param dept
         * @return
         */
        @RequestMapping("/consumer/dept/add")
        public boolean add(Dept dept) {
            return deptClientService.addDept(dept);
        }
    
        /**
         * 消费方根据id查询部门信息
         * @param id
         * @return
         */
        @RequestMapping("/consumer/dept/get/{id}")
        public Dept get(@PathVariable("id") Long id) {
           return deptClientService.queryById(id);
        }
    
        /**
         * 消费方查询部门信息列表
         * @return
         */
        @RequestMapping("/consumer/dept/list")
        public List<Dept> list() {
            return deptClientService.queryAll();
        }
    }
    

    FeignRibbon 二者对比,前者显现出面向接口编程特点,代码看起来更清爽,而且Feign调用方式更符合我们之前在做SSM或者SpringBoot项目时,Controller层调用Service层的编程习惯!

    主配置类

    @SpringBootApplication
    @EnableEurekaClient
    // feign客户端注解,并指定要扫描的包以及配置接口DeptClientService
    @EnableFeignClients(basePackages = {"com.haust.springcloud"})
    // 切记不要加这个注解,不然会出现404访问不到
    //@ComponentScan("com.haust.springcloud")
    public class FeignDeptConsumer_80 {
        public static void main(String[] args) {
            SpringApplication.run(FeignDeptConsumer_80.class, args);
        }
    }
    
  2. 改造springcloud-api模块

    pom.xml 添加feign依赖

    <!--Feign的依赖-->
    <dependency>
       <groupId>org.springframework.cloud</groupId>
       <artifactId>spring-cloud-starter-feign</artifactId>
       <version>1.4.6.RELEASE</version>
    </dependency>
    

    新建service包,并新建DeptClientService.java接口,

    	// @FeignClient:微服务客户端注解,value:指定微服务的名字,这样就可以使Feign客户端直接找到对应的微服务
    @FeignClient(value = "SPRINGCLOUD-PROVIDER-DEPT")
    public interface DeptClientService {
    
        @GetMapping("/dept/get/{id}")
        public Dept queryById(@PathVariable("id") Long id);
    
        @GetMapping("/dept/list")
        public Dept queryAll();
    
        @GetMapping("/dept/add")
        public Dept addDept(Dept dept);
    }
    

3. Feign 和 Ribbon 如何选择


根据个人习惯而定,如果喜欢REST风格使用Ribbon;如果喜欢社区版的面向接口风格使用Feign。

Feign 本质上也是实现了 Ribbon,只不过后者是在调用方式上,为了满足一些开发者习惯的接口调用!

下面我们关闭 springcloud-consumer-dept-80 这个服务消费方,换用springcloud-consumer-dept-feign(端口还是80)来代替:(依然可以正常防访问,就是调用方式相比于Ribbon变化了)

在这里插入图片描述

posted on   JAVA开发区  阅读(28)  评论(0编辑  收藏  举报  
相关博文:
阅读排行:
· DeepSeek 开源周回顾「GitHub 热点速览」
· 物流快递公司核心技术能力-地址解析分单基础技术分享
· .NET 10首个预览版发布:重大改进与新特性概览!
· AI与.NET技术实操系列(二):开始使用ML.NET
· 单线程的Redis速度为什么快?
点击右上角即可分享
微信分享提示