开课吧孤尽T31训练营学习笔记-DAY23-微服务之OpenFeign实战

62 阅读2分钟

微服务至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接口实现

注意点:

  1. 接口实现并不是需要一个类必须去实现2.1中定义的接口;而是只需要有对应的url即可,并且参数和返回值保持一致。
  2. 该服务在服务注册中心注册的名字和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;

像调用本地接口一样,自由的使用吧。