1. 目标
这是服务端提供的接口。
@RestController
@RequestMapping("user")
@Slf4j
public class UserController {
@GetMapping("info")
public User getUser(@RequestParam Long id) {
log.info("getUser, id : {}", id);
User user = new User();
user.setId(id);
user.setSex(1);
user.setEmail("23132132@qq.com");
user.setUsername("qyh");
return user;
}
@PostMapping("save")
public R saveUser(@RequestBody User user) {
log.info("user : {}", user);
return R.success(user);
}
}
现在想要达成的效果是客户端只需要书写如下代码,就能成功调用服务端。
@FeignClient(url = "localhost:12345/user")
public interface UserClient {
@GetMapping("info")
User getUserById(@RequestParam("id") Long id);
@PostMapping("save")
R saveUser(@RequestBody User user);
}
我们可以发现,客户端代码和服务端代码长得一模一样,其他地方怎么调用呢?
@RestController
@RequestMapping("test")
public class TestController {
final UserClient userClient;
public TestController(UserClient userClient) {
this.userClient = userClient;
}
@GetMapping("getUserById")
public User getUserById(@RequestParam long id) {
return userClient.getUserById(id);
}
@GetMapping("saveUser")
public R saveUser(@RequestParam Map<String, Object> params) {
String username = (String) params.get("username");
Integer sex = Integer.parseInt((String) params.get("sex"));
String email = (String) params.get("email");
Long id = Long.parseLong((String) params.get("id"));
User user = new User();
user.setId(id);
user.setUsername(username);
user.setSex(sex);
user.setEmail(email);
return userClient.saveUser(user);
}
}
这样就简化了一堆开发的代码。只需要赋值服务端的接口代码,然后就像调用本地方法一样调用远程方法。这就是RPC的精髓所在。
下面介绍一下设计该RPC框架的技术
2. 设计思路
2.1 factoryBean
factoryBean是spring提供构建复杂对象的技术,常见的框架例如mybatis整合spring,openFeign整合spring都是采用factoryBean来构建的。所以要完成这种用代理对象完成接口实现的套路。