程序员社区

SpringCloud构建微服务之Feign声明式服务调用

前言

在讲前面几篇文章的时候,消费者服务与提供者服务之间是利用RestTemplate进行通信的。这种方式是属于面向服务编程,那么在实际开发中,对服务依赖的客户端可能会有很多,每个客户端都需要对这些依赖的服务调用进行封装,大大增加的工作量。因此,SpringCloud就提供了一种解决方案,面向接口编程的声明式服务调用——Feign,只需简单的声明一下微服务接口,即可进行服务之间的通信,从而大大减轻的工作量。

什么是Feign?

Feign是一个声明式WebService客户端。使用Feign能让编写Web Service客户端更加简单, 它的使用方法是定义一个接口,然后在上面添加注解,同时也支持JAX-RS标准的注解。Feign也支持可拔插式的编码器和解码器。Spring CloudFeign进行了封装,使其支持了Spring MVC标准注解和HttpMessageConvertersFeign可以与EurekaRibbon组合使用以支持负载均衡。

官方介绍:http://projects.spring.io/spring-cloud/spring-cloud.html#spring-cloud-feign
GitHub:https://github.com/OpenFeign/feign
在这里插入图片描述
前面在使用RestTemplate时,利用RestTemplate对http请求的封装处理,形成了一套模版化的调用方法。但是在实际开发中,由于对服务依赖的调用可能不止一处, 往往一个接口会被多处调用,所以通常都会针对每个微服务自行封装一些客户端类来包装这些依赖服务的调用。 所以,Feign在此基础上做了进一步封装,由他来帮助我们定义和实现依赖服务接口的定义。在Feign的实现下, 我们只需创建一个接口并使用注解的方式来配置它(以前是Dao接口上面标注Mapper注解,现在是一个微服务接口上面标注一个Feign注解即可) ,即可完成对服务提供方的接口绑定,优雅而简单的实现了服务调用 ,简化了使用Spring cloud Ribbon时,自动封装服务调用客户端的开发量。

集成Feign

创建一个名称为spring-cloud-apimodule
在这里插入图片描述
修改pom文件,增加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-examples</artifactId>
        <groupId>com.chaytech</groupId>
        <version>1.0-SNAPSHOT</version>
    </parent>
    <modelVersion>4.0.0</modelVersion>

    <artifactId>spring-cloud-api</artifactId>
    <packaging>jar</packaging>

    <dependencies>
        <dependency>
            <groupId>com.chaytech</groupId>
            <artifactId>spring-cloud-model</artifactId>
            <version>${project.version}</version>
        </dependency>
        <dependency>
            <groupId>org.projectlombok</groupId>
            <artifactId>lombok</artifactId>
        </dependency>

        <!--feign-->
        <dependency>
            <groupId>org.springframework.cloud</groupId>
            <artifactId>spring-cloud-starter-feign</artifactId>
        </dependency>
    </dependencies>
</project>

创建一个名称为UserApi的接口,并添加FeignClient注解:

@FeignClient(value = "USER-PROVIDER")
public interface UserApi {

    @PostMapping("/user/createUser")
    public boolean createUser(@RequestBody UserEntity user);

    @GetMapping("/user/getUser/{id}")
    public UserEntity getUser(@PathVariable("id") Integer id);

    @GetMapping("/user/listUser")
    public List<UserEntity> listUser();
} 

将此工程maven install,如果打包失败,找到父工程,maven install

创建feign客户端module(spring-cloud-consumer-user-feign):
在这里插入图片描述
spring-cloud-consumer-user的代码和配置文件copy一份到此工程下。
修改pom文件,增加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-examples</artifactId>
        <groupId>com.chaytech</groupId>
        <version>1.0-SNAPSHOT</version>
    </parent>
    <modelVersion>4.0.0</modelVersion>

    <artifactId>spring-cloud-consumer-user-feign</artifactId>
    <packaging>jar</packaging>

    <dependencies>
        <dependency>
            <groupId>com.chaytech</groupId>
            <artifactId>spring-cloud-model</artifactId>
            <version>${project.version}</version>
        </dependency>
        <dependency>
            <groupId>com.chaytech</groupId>
            <artifactId>spring-cloud-api</artifactId>
            <version>${project.version}</version>
        </dependency>

        <dependency>
            <groupId>org.springframework.boot</groupId>
            <artifactId>spring-boot-starter-web</artifactId>
        </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>

        <!--feign-->
        <dependency>
            <groupId>org.springframework.cloud</groupId>
            <artifactId>spring-cloud-starter-feign</artifactId>
        </dependency>

        <!-- 修改后立即生效,热部署 -->
        <dependency>
            <groupId>org.springframework</groupId>
            <artifactId>springloaded</artifactId>
        </dependency>
        <dependency>
            <groupId>org.springframework.boot</groupId>
            <artifactId>spring-boot-devtools</artifactId>
        </dependency>
    </dependencies>
</project>

修改UserController,将原有的RestTemplate调用方式修改为feign调用:

@RestController
public class UserController {

    @Autowired
    private UserApi userApi;

    @PostMapping("/consumer/user/add")
    public boolean add(UserEntity user) {
        return userApi.createUser(user);
    }

    @GetMapping("/consumer/user/getUser/{id}")
    public UserEntity get(@PathVariable("id") Integer id) {
        return userApi.getUser(id);
    }

    @GetMapping("/consumer/user/listUser")
    public List<UserEntity> list() {
        return userApi.listUser();
    }
}

修改启动类,增加@EnableFeignClients注解:
此处注意,如果你的feign接口的包路径与feign客户端路径不一致,则需要指定basePackages,否则将会扫描不到feign接口,导致注入失败。

@SpringBootApplication
// 本服务启动后会自动注册进eureka服务中
@EnableEurekaClient
@EnableFeignClients(basePackages ={"com.chaytech.api"} )
public class UserConsumerFeign80_Application {

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

测试

分别启动eureka集群、部门微服务集群、feign客户端服务

还是请求同一个地址:127.0.01:8080/consumer/user/listUser

在这里插入图片描述
接口正常返回数据,至此,集成feign进行声明式服务调用成功!

赞(0) 打赏
未经允许不得转载:IDEA激活码 » SpringCloud构建微服务之Feign声明式服务调用

一个分享Java & Python知识的社区