Feign是一个声明式WebService客户端,使用方法是定义一个接口并在上面添加注解即可。Feign支持可拔插式的编码器和解码器。

 

Spring Cloud对Feign进行了封装,使其支持SpringMVC和HttpMessageConverters。Feign可以与Eureka和Ribbon组合使用以支持负载均衡。

[Feign源码]: https://github.com/OpenFeign/Feign

 

使用案例:

1.新建一个Feign模块,类似之前Ribbon中使用的consume-9001模块。在依赖信息中加入Feign的依赖;

<?xml version="1.0" encoding="UTF-8"?>
<project xmlns="http://maven.apache.org/POM/4.0.0"
         xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
         xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd">
    <parent>
        <artifactId>spring-cloud-demo</artifactId>
        <groupId>com.wangcw.springcloud</groupId>
        <version>1.0-SNAPSHOT</version>
    </parent>
    <modelVersion>4.0.0</modelVersion>

    <artifactId>springclouddemo-consume-feign-9002</artifactId>

    <dependencies>
        <!--Feign模块依赖-->
        <dependency>
            <groupId>org.springframework.cloud</groupId>
            <artifactId>spring-cloud-starter-feign</artifactId>
        </dependency>
        <!-- 自己定义的api -->
        <dependency>
            <groupId>com.wangcw.springcloud</groupId>
            <artifactId>springclouddemo-api</artifactId>
            <version>${project.version}</version>
        </dependency>
        <!-- Ribbon相关 -->
        <dependency>
            <groupId>org.springframework.cloud</groupId>
            <artifactId>spring-cloud-starter-eureka</artifactId>
        </dependency>
        <dependency>
            <groupId>org.springframework.cloud</groupId>
            <artifactId>spring-cloud-starter-ribbon</artifactId>
        </dependency>
        <dependency>
            <groupId>org.springframework.cloud</groupId>
            <artifactId>spring-cloud-starter-config</artifactId>
        </dependency>
        <dependency>
            <groupId>org.springframework.boot</groupId>
            <artifactId>spring-boot-starter-web</artifactId>
        </dependency>
    </dependencies>

</project>

2. 因为Feign开发其实是面向接口编程,所以Feign接口可以放在公共模块【springclouddemo-api】模块中供各模块使用,所以要在【springclouddemo-api】模块中添加也添加Feign依赖;

<?xml version="1.0" encoding="UTF-8"?>
<project xmlns="http://maven.apache.org/POM/4.0.0"
         xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
         xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd">
    <parent>
        <artifactId>spring-cloud-demo</artifactId>
        <groupId>com.wangcw.springcloud</groupId>
        <version>1.0-SNAPSHOT</version>
    </parent>
    <modelVersion>4.0.0</modelVersion>

    <artifactId>springclouddemo-api</artifactId>

    <dependencies>
        <!--Feign依赖-->
        <dependency>
            <groupId>org.springframework.cloud</groupId>
            <artifactId>spring-cloud-starter-feign</artifactId>
        </dependency>
        <!--mybatis-->
        <dependency>
            <groupId>org.mybatis.spring.boot</groupId>
            <artifactId>mybatis-spring-boot-starter</artifactId>
            <version>1.3.0</version>
        </dependency>
        <dependency>
            <groupId>tk.mybatis</groupId>
            <artifactId>mapper-spring-boot-starter</artifactId>
            <version>2.0.0</version>
        </dependency>
        <dependency>
            <groupId>javax.persistence</groupId>
            <artifactId>persistence-api</artifactId>
            <version>1.0.2</version>
        </dependency>

        <dependency>
            <groupId>org.projectlombok</groupId>
            <artifactId>lombok</artifactId>
        </dependency>
    </dependencies>

</project>

3.公共模块【springclouddemo-api】中编写接口,接口上添加@FeignClient注解,并通过value指定作用的微服务名;

package com.wangcw.service;


/* 新建Feign接口供各个模块调用微服务 【SPRINGCLOUDDEMO-PROVIDER-DEPT】*/
@FeignClient(value = "SPRINGCLOUDDEMO-PROVIDER-DEPT")
public interface FeignClientService{

	@RequestMapping(value = "/provider/dept/get/{id}", method = RequestMethod.GET)
	Dept get(@PathVariable("id") long id);

	@RequestMapping(value = "/provider/dept/list", method = RequestMethod.GET)
	List<Dept> list();

}

 

4.在步骤1中新建的Feign模块中编写Controller,并注入FeignClient接口,直接调用service接口中的方法即可(因为声明Feign接口时已经指定过微服务,所以访问时会正确地找到微服务)

 

@RestController
@RequestMapping(value = "/consumer")
public class DeptController_Consumer {

    /* 注入公共模块中的FeignService */
    @Autowired
    private FeignClientService feignClientService;

    @RequestMapping(value = "/dept/get/{id}")
    public Dept get(@PathVariable("id") Long id) {
        return this.feignClientService.get(id);
    }

    @RequestMapping(value = "/dept/list")
    public List<Dept> list() {
        return this.feignClientService.list();
    }


}

 

5.修改Feign模块的主启动类,加入@EnableFeignClients注解(主要是扫描公共模块【springclouddemo-api中声明的接口)

 

@SpringBootApplication(exclude = {DataSourceAutoConfiguration.class, HibernateJpaAutoConfiguration.class})
@EnableEurekaClient
@EnableFeignClients(basePackages= {"com.wangcw.service"})
public class DeptConsumer_Feign_9002_App {
    public static void main(String[] args) {
        SpringApplication.run(DeptConsumer_Feign_9002_App.class, args);
    }
}

6.启动访问测试,会发现访问时带有轮询机制的负载均衡。

(原理:其实就是类似于在公共工程api中加入Service接口,在接口中利用@FeignClient注解去调用对应的服务暴露的方法。

   所有需要调用注册的服务的类都直接去调用api中的service,即相当于是在调用对应的在线服务了)

 

总结:
- Feign通过接口方法调用REST服务,在Eureka中查找对应的服务

- Feign集成了Ribbon技术,所以也支持负载均衡(默认轮询,如需要替换可以在将自己需要的规则添加到容器中,如上一节Ribbon的方式)

 

需要源码请留下邮箱或者关注左侧的微信公众号!

Logo

权威|前沿|技术|干货|国内首个API全生命周期开发者社区

更多推荐