我们知道,现在最火且最有技术含量的技术莫过于SpringCloud微服务了,所以今天壹哥就带大家来学习一下微服务的核心的组件之一,Feign的基本使用及其工作机制。
在学习Feign的使用之前,我们先来了解一下什么是Feign。
Feign是Netflix开发的声明式(目前由Spring在维护)、模板化的HTTP客户端, Feign可以帮助我们更快捷、优雅地调用HTTP Api。
简单地来说,Feign就是一个用于远程调用服务的框架/工具,让开发者可以更少耦合、更少代码、更加快,也更兼容的方法进行远程服务调用。
Feign可插拔的注解支持,包括Feign注解和JAX-RS注解;
Feign与Ribbon负载均衡器、Hystrix或Sentinel熔断器无缝集成;
Feign支持可插拔的HTTP编码器和解码器;
Feign支持HTTP请求和响应的压缩等。
了解了这些基本概念之后,接下来壹哥就带大家看看Feign组件是如何实现远程接口调用的。废话少说,我们直接上代码。
首先我们在父POM文件中添加核心依赖如下:
- <dependencyManagement>
- <dependencies>
- <dependency>
- <groupId>org.springframework.cloudgroupId>
- <artifactId>spring-cloud-dependenciesartifactId>
- <version>${spring-cloud.version}version>
- <type>pomtype>
- <scope>importscope>
- dependency>
-
- <dependency>
- <groupId>com.alibaba.cloudgroupId>
- <artifactId>spring-cloud-alibaba-dependenciesartifactId>
- <version>${spring-cloud-alibaba-dependencies.version}version>
- <type>pomtype>
- <scope>importscope>
- dependency>
- dependencies>
- dependencyManagement>
然后在子POM文件添加依赖如下:
- <dependency>
- <groupId>org.springframework.cloudgroupId>
- <artifactId>spring-cloud-starter-openfeignartifactId>
- dependency>
- <dependency>
- <groupId>com.alibaba.cloudgroupId>
- <artifactId>spring-cloud-starter-alibaba-nacos-discoveryartifactId>
- dependency>
application.yml文件中添加如下配置:
- server:
- port: 8090
- spring:
- application:
- name: nacos-feign-example
- cloud:
- nacos:
- discovery:
- server-addr: 112.74.42.138:8848
项目的启动类代码如下:
- @SpringBootApplication
- public class NetflixFeignProviderApplication {
- public static void main(String[] args) {
- SpringApplication.run(NetflixFeignProviderApplication.class, args);
- }
- }
我们可以编写一个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
users(@RequestHeader("token") String token) { - // 模拟从数据中获取数据
- ArrayList
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;
- }
- }
这里再定义一个pojo实体类。
- @Data
- @AllArgsConstructor
- @NoArgsConstructor
- @Builder
- public class User implements Serializable {
- private Integer uid;
- private String username;
- private String password;
- }
消费者服务的核心依赖如下:
- <dependency>
- <groupId>org.springframework.cloudgroupId>
- <artifactId>spring-cloud-starter-openfeignartifactId>
- dependency>
-
- <dependency>
- <groupId>org.springframework.bootgroupId>
- <artifactId>spring-boot-starter-webartifactId>
- dependency>
-
- <dependency>
- <groupId>com.alibaba.cloudgroupId>
- <artifactId>spring-cloud-starter-alibaba-nacos-discoveryartifactId>
- dependency>
消费者服务的application.yml配置文件如下:
- server:
- port: 8091
- spring:
- cloud:
- nacos:
- discovery:
- server-addr: 你的注册中心IP:8848
- application:
- name: feign-example-01
消费者服务的启动类代码。
- @SpringBootApplication
- // 开启Feign
- @EnableFeignClients
- public class NetflixFeignClientApplication {
- public static void main(String[] args) {
- SpringApplication.run(NetflixFeignClientApplication.class, args);
- }
- }
这里也需要定义一个POJO类,代码同上,此处略过。
此处我们需要定义一个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
users(@RequestHeader("token") String token); - }
然后我们也需要在消费者服务中定义一个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
users(@RequestHeader String token) { - return userFeignService.users(token);
- }
- }
代码编写完毕后,我们需要将服务提供者和服务消费者两个项目都启动起来,然后进行测试。



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