一. 概要
我们知道,现在最火且最有技术含量的技术莫过于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.测试头部中包含信息
通过测试我们就可以发现,测试我们已经实现了在服务消费者中原创调用服务提供者里的接口,从而实现了接口的远程调用。