微服务至OpenFeign实战
虽然网上材料有很多,但是在实际用的过程中,还是遇到了一些坑。这里就分享一下再课程实战过程中,排查坑的过程。
一、使用场景说明
认证中心服务auth-center在做用户认证时,需要去admin-server获取用户信息;根据登录用户名获取用户信息,然后做密码检查,认证通过后,发放令牌。
根据这个场景,我们可以认为 admin-server是服务提供者,auth-center是服务消费者。接下来,我们分开说明一下服务消费者和服务提供者的实践经验。
二、实战之服务提供者
2.1 provider提供的接口定义
服务提供者,首先将服务接口和DTO单独定义出来,以供其他消费者使用。
1. 声明依赖
使用lombok方便定义DTO。
<dependencies>
<dependency>
<groupId>org.springframework.cloud</groupId>
<artifactId>spring-cloud-starter-openfeign</artifactId>
</dependency>
<dependency>
<groupId>org.projectlombok</groupId>
<artifactId>lombok</artifactId>
</dependency>
</dependencies>
2. 定义DTO
根据阿里巴巴Java开发规范,接口提供的数据使用DTO封装.
3. 定义接口
声明FeignClinet, 本实例中使用nacos作为服务注册中心, value值对应nacos注册的服务提供者名称。
@FeignClient(value = "t31-admin")
public interface UserClient {
@GetMapping("/api/v1/user")
UserDTO getByUsername(@RequestParam String username);
@GetMapping("/api/v1/user/role-list")
List<String> listRolesByUserId(@RequestParam Long userId);
}
注意避坑1:如果是url中的参数,必须声明注解“RequestParam”,否则被认为是post请求,拿不到数据,会报400错误。
2.2 provider接口实现
注意点:
- 接口实现并不是需要一个类必须去实现2.1中定义的接口;而是只需要有对应的url即可,并且参数和返回值保持一致。
- 该服务在服务注册中心注册的名字和FeignClient中声明的名字一致。
首先在pom中,引用api,主要是为了复用DTO。
<dependency>
<groupId>com.kaikeba</groupId>
<artifactId>t31-admin-api</artifactId>
<version>1.0.0-SNAPSHOT</version>
</dependency>
然后在controller中实现对应的url即可:
@RestController
@RequestMapping(value = "/api/v1/user")
public class UserClientController {
@Autowired
private SysUserService sysUserService;
@Autowired
private SysRoleService sysRoleService;
@GetMapping("")
public UserDTO getUserByUsername(String username) {
SysUserEntity user = sysUserService.queryByUserName(username);
UserDTO userDTO = new UserDTO();
userDTO.setId(user.getUserId());
userDTO.setUsername(user.getUsername());
userDTO.setPassword(user.getPassword());
return userDTO;
}
@GetMapping("role-list")
public List<String> listRoleByUserId(Long userId) {
List<String> list = this.sysRoleService.listRoleNameList(userId);
return list;
}
}
至此,服务提供者已经搞定。
三、实战之服务消费者
服务消费者的使用就很简单,只需要引入对应的接口即可,将其视为普通的service。
首先pom引入接口定义,就是为了使用服务和DTO。
<dependency>
<groupId>com.kaikeba</groupId>
<artifactId>t31-admin-api</artifactId>
<version>1.0.0-SNAPSHOT</version>
</dependency>
在需要调用这个接口的地方注入即可:
@Autowired
UserClient userClient;
像调用本地接口一样,自由的使用吧。