OpenFeig是一种声明式REST客户端。OpenFeig通过使用JAX-RS或SpringMVC注解的修饰方式,生成接口的动态实现(伪客户端)。
OpenFeig是用于消费者调用提供者的,所以OpenFeig只涉及消费者。
OpenFeign具有负载均衡功能,其可以对指定的微服务采用负载均衡方式进行消费、访问。
一、提供者
创建一个模块,这个模块中的某些接口可能会被其它模块调用,所以它叫做提供者。(注:下文中会称该模块为A模块)
1.1 引入依赖
使用OpenFeign必须与Nacos服务注册中心组件结合使用,所以提供者的依赖中要添加服务注册中心依赖(nacos-discovery)。
因为OpenFeig只涉及消费者,所以不用在提供者中添加OpenFeig依赖。
<parent>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-parent</artifactId>
<version>3.0.6</version>
<relativePath/>
</parent>
<dependencies>
<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>
<version>2022.0.0.0-RC2</version>
</dependency>
<dependency>
<groupId>org.projectlombok</groupId>
<artifactId>lombok</artifactId>
<optional>true</optional>
</dependency>
</dependencies>
1.2 配置文件
server:
port: 8090
spring:
application:
name: service-ssm # 微服务名称
cloud:
nacos:
discovery:
server-addr: localhost:8848
username: nacos
password: nacos
1.3 编写实体类
创建一个实体类,进行模拟使用。
@Data
@NoArgsConstructor
@AllArgsConstructor
public class User {
private Integer id;
private String name;
}
1.4 编写控制层代码
控制器层,这里为了方便没有写业务层代码和持久层代码,而是写了一个allUser方法来模拟调用。
@RequestMapping("/ssm")
@RestController
public class UserController {
//@Resource
//private UserService userService;
@GetMapping("/selectAllUser")
public List<User> selectAllUser() {
// List<User> userList = userService.allUser();
List<User> userList = allUser();
return userList;
}
// 模拟数据查询
public static List<User> allUser() {
ArrayList<User> userList = new ArrayList<>();
userList.add(new User(001, "小明"));
userList.add(new User(002, "小红"));
userList.add(new User(003, "小张"));
userList.add(new User(004, "小王"));
return userList;
}
}
二、消费者
再创建一个模块,这个模块想要去调用A模块中的某些方法,可以使用OpenFeign生成接口的动态实现,然后就可以调用A模块中的接口了。
2.1 引入依赖
使用OpenFeign必须与Nacos服务注册中心组件结合使用,所以提供者的依赖中要添加服务注册中心依赖(nacos-discovery)。
因为OpenFeig只涉及消费者,所以要在消费者中添加OpenFeig依赖。
从Spring Cloud 2021.x开始,OpenFeign采用Spring Cloud自行研发的Spring Cloud Loadbalancer作为负载均衡器,所以要引入loadbalancer依赖。
<parent>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-parent</artifactId>
<version>3.0.6</version>
<relativePath/>
</parent>
<dependencies>
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-web</artifactId>
</dependency>
<!-- openfeign依赖 -->
<dependency>
<groupId>org.springframework.cloud</groupId>
<artifactId>spring-cloud-starter-openfeign</artifactId>
<version>4.0.0</version>
</dependency>
<!-- loadbalancer依赖 -->
<dependency>
<groupId>org.springframework.cloud</groupId>
<artifactId>spring-cloud-starter-loadbalancer</artifactId>
<version>4.0.0</version>
</dependency>
<dependency>
<groupId>com.alibaba.cloud</groupId>
<artifactId>spring-cloud-starter-alibaba-nacos-discovery</artifactId>
</dependency>
<dependency>
<groupId>org.projectlombok</groupId>
<artifactId>lombok</artifactId>
<optional>true</optional>
</dependency>
</dependencies>
2.2 配置文件
server:
port: 8080
spring:
application:
name: service-openfeign # 微服务名称
cloud:
nacos:
discovery:
server-addr: localhost:8848
username: nacos
password: nacos
2.3 编写实体类
因为接下来会使用到User实体类,如果不创建就会报错,所以要创建一个与提供者相同的实体类。如果你自己业务中,接口返回值、参数中不涉及到实体类,可以不用创建。
@Data
@NoArgsConstructor
@AllArgsConstructor
public class User {
private Integer id;
private String name;
}
2.4 定义Feign接口
Feign的接口名可以是任意的名称,接口中的方法名也可以是任意的名称。但@FeignClient参数指定的提供者服务名称是不能修改的,接口与方法上添加的@XxxMapping中的参数是不能修改的,必须与提供者相应的请求URI相同。
一句话概括,就是把想要调用的提供者控制器复制过来,然后去掉方法体。(注意路径要完整)
@FeignClient("service-ssm")
public interface UserService {
@GetMapping("/ssm/selectAllUser")
public List<User> selectAllUser();
}
2.5 编写控制层代码
在处理器中使用Feign接口进行调用其他模块的接口。
@RequestMapping("/openfeign")
@RestController
public class UserController {
@Resource
private UserService userService;
@GetMapping("/selectAllUser")
public List<User> selectAllUser() {
HashMap<String, Object> hashMap = new HashMap<>();
List<User> userList = userService.selectAllUser();
hashMap.put("userList", userList);
hashMap.put("message", "这是消费者模块,OpenFeign!!!");
return hashMap;
}
}
2.6 编写启动类
在启动类上添加@EnableFeignClients注解。
@EnableFeignClients
@SpringBootApplication
public class SentinelApplication {
public static void main(String[] args) {
SpringApplication.run(SentinelApplication.class, args);
}
}
三、测试
启动两个模块的实体类,在Nacos控制台的服务列表中可以看见两个模块的微服务名称即可。
在Postman中访问提供者的控制器,即访问A模块中自己的方法,是没有问题的。
在Postman中访问消费者的控制器,即在B模块中去调用A模块中的方法,OpenFeign起到作用。