当服务端接收并解析来自客户端发出的数据之后,该如何调用客户端希望调用的方法呢?这主要是通过反射实现的。
在服务启动发布的过程中,在服务端已经存储了服务名和对应Bean的映射:
private final Map<String, Object> serviceMap;
private final Set<String> registeredService;
@Override
public void addService(RpcServiceConfig rpcServiceConfig) {
String rpcServiceName = rpcServiceConfig.getRpcServiceName();
if (registeredService.contains(rpcServiceName)) {
return;
}
registeredService.add(rpcServiceName);
serviceMap.put(rpcServiceName, rpcServiceConfig.getService());
log.info("Add service: {} and interfaces:{}", rpcServiceName, rpcServiceConfig.getService().getClass().getInterfaces());
}
接收到对应数据后,首先就是需要找到对应的Bean,找到对应的Bean后,就可以使用反射调用对应方法:
public Object handle(RpcRequest rpcRequest) {
Object service = serviceProvider.getService(rpcRequest.getRpcServiceName());
return invokeTargetMethod(rpcRequest, service);
}
private Object invokeTargetMethod(RpcRequest rpcRequest, Object service) {
Object result;
try {
Method method = service.getClass().getMethod(rpcRequest.getMethodName(), rpcRequest.getParamTypes());
result = method.invoke(service, rpcRequest.getParameters());
log.info("service:[{}] successful invoke method:[{}]", rpcRequest.getInterfaceName(), rpcRequest.getMethodName());
} catch (NoSuchMethodException | IllegalArgumentException | InvocationTargetException | IllegalAccessException e) {
throw new RpcException(e.getMessage(), e);
}
return result;
}
}
getService就是从服务端注册时的本地缓存中取出Bean。得到Bean后接下来需要根据方法名和方法的参数类型来获取到对应方法,获取到之后再调用方法获取结果,并返回。
获取到相应结果之后,再按照相应的通信规则进行包装处理,发送给客户端进行响应。