一. 概要

我们知道,现在最火且最有技术含量的技术莫过于SpringCloud微服务了,所以今天壹哥就带大家来学习一下微服务的核心的组件之一,Feign的基本使用及其工作机制。

. Feign简介

1. 概念

在学习Feign的使用之前,我们先来了解一下什么是Feign。

Feign是Netflix开发的声明式(目前由Spring在维护)、模板化的HTTP客户端, Feign可以帮助我们更快捷、优雅地调用HTTP Api。

简单地来说,Feign就是一个用于远程调用服务的框架/工具,让开发者可以更少耦合、更少代码、更加快,也更兼容的方法进行远程服务调用。

2. 功能

  • Feign可插拔的注解支持,包括Feign注解和JAX-RS注解;

  • Feign与Ribbon负载均衡器、Hystrix或Sentinel熔断器无缝集成;

  • Feign支持可插拔的HTTP编码器和解码器;

  • Feign支持HTTP请求和响应的压缩等。

了解了这些基本概念之后,接下来壹哥就带大家看看Feign组件是如何实现远程接口调用的。废话少说,我们直接上代码。

三. 服务提供者

1. 添加依赖

首先我们在父POM文件中添加核心依赖如下:

<dependencyManagement>
  <dependencies>
    <dependency>
      <groupId>org.springframework.cloud</groupId>
      <artifactId>spring-cloud-dependencies</artifactId>
      <version>${spring-cloud.version}</version>
      <type>pom</type>
      <scope>import</scope>
    </dependency>
    
    <dependency>
      <groupId>com.alibaba.cloud</groupId>
      <artifactId>spring-cloud-alibaba-dependencies</artifactId>
      <version>${spring-cloud-alibaba-dependencies.version}</version>
      <type>pom</type>
      <scope>import</scope>
    </dependency>
  </dependencies>
</dependencyManagement>

然后在子POM文件添加依赖如下:

<dependency>
  <groupId>org.springframework.cloud</groupId>
  <artifactId>spring-cloud-starter-openfeign</artifactId>
</dependency>
<dependency>
  <groupId>com.alibaba.cloud</groupId>
  <artifactId>spring-cloud-starter-alibaba-nacos-discovery</artifactId>
</dependency>

2. 配置文件

application.yml文件中添加如下配置:

server:
  port: 8090
spring:
  application:
    name: nacos-feign-example
  cloud:
    nacos:
      discovery:
        server-addr: 112.74.42.138:8848

3. 启动类

项目的启动类代码如下:

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

4. 控制层

我们可以编写一个Controller控制器,将Web接口定义如下。

@RestController
@RequestMapping("/user")
@Slf4j
public class UserController {
    /**
     * 模拟主键自增
     */
    private AtomicInteger pk = new AtomicInteger();
    
    @PostMappingpublic User save(@RequestBody User user) {
        user.setUid(pk.incrementAndGet());
        return user;
    }

    /**
     * @param uid
     * @return
     */@GetMapping("/{uid}")
    public User user(@PathVariable("uid") int uid) {
        return User.builder()
                .uid(uid)
                .username("admin")
                .password("123456")
                .build();
    }

    @GetMapping("/users")
    public List<User> users(@RequestHeader("token") String token) {
        // 模拟从数据中获取数据
        ArrayList<User> users = new ArrayList<>();
        for (int i = 1; i <= 10; i++) {
            users.add(User.builder()
                    .uid(i)
                    .username(token + i)
                    .password("123456")
                    .build());
        }
        return users;
    }

    @DeleteMapping()
    public int delete(int uid) {
        log.info("删除用户: {} 成功", uid);
        return 1;
    }
}

5. POJO

这里再定义一个pojo实体类。

@Data
@AllArgsConstructor
@NoArgsConstructor
@Builder
public class User implements Serializable {
    private Integer uid;
    private String username;
    private String password;
}

四. 服务消费者

1. 添加依赖

消费者服务的核心依赖如下:

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

<dependency>
    <groupId>org.springframework.boot</groupId>
    <artifactId>spring-boot-starter-web</artifactId>
</dependency>

<dependency>
    <groupId>com.alibaba.cloud</groupId>
    <artifactId>spring-cloud-starter-alibaba-nacos-discovery</artifactId>
</dependency>

2. 配置文件

消费者服务的application.yml配置文件如下:

server:
  port: 8091
spring:
  cloud:
    nacos:
      discovery: 
        server-addr: 你的注册中心IP:8848
      application:
        name: feign-example-01

3. 启动类

消费者服务的启动类代码。

@SpringBootApplication
// 开启Feign
@EnableFeignClients
public class NetflixFeignClientApplication {
    public static void main(String[] args) {
        SpringApplication.run(NetflixFeignClientApplication.class, args);
    }
}

这里也需要定义一个POJO类,代码同上,此处略过。

4. Feign服务

此处我们需要定义一个Feign接口类。

@FeignClient(value = "test-feign-provider", path = "/user")
public interface UserFeignService {
    @PostMapping("/")
    User save(@RequestBody User user);

    @GetMapping("/{uid}")
    User detail(@PathVariable("uid") int uid);

    @DeleteMappingUser delete(@RequestParam int uid);

    @GetMapping("/users")
    List<User> users(@RequestHeader("token") String token);
}

5. 控制层

然后我们也需要在消费者服务中定义一个Controller接口。

@RestController
@RequestMapping("/feign")
public class FeignController {
    @Resource
    UserFeignService userFeignService;
    
    /**
     *  传递复杂的对象 json格式
     * 127.0.0.1:8091/feign/register
     */@PostMapping("/register")
    public User register(@RequestBody User user) {
        return userFeignService.save(user);
    }
    /**
     * 127.0.0.1:8091/feign/1
     */@GetMapping("/{uid}")
    public User detail(@PathVariable int uid) {
        return userFeignService.detail(uid);
    }
    /**
     * 127.0.0.1:8091/feign/users
     * 
     */@GetMapping("/users")
    public List<User> users(@RequestHeader String token) {
        return userFeignService.users(token);
    }
}

代码编写完毕后,我们需要将服务提供者和服务消费者两个项目都启动起来,然后进行测试。

五. 测试

1. 测试get请求

2. 测试post请求,json数据格式

3. 测试头部中包含信息

通过测试我们就可以发现,测试我们已经实现了在服务消费者中原创调用服务提供者里的接口,从而实现了接口的远程调用。现在你学会了吗?如果你还不明白,可以私信我哦。

Logo

华为开发者空间,是为全球开发者打造的专属开发空间,汇聚了华为优质开发资源及工具,致力于让每一位开发者拥有一台云主机,基于华为根生态开发、创新。

更多推荐