源码分析:Jsonrpc的标准|泛化调用执行流程
背景
在jsonrpc的服务化调用中,如果客户端使用多种调用姿势,比如jsonrpc的标准调用、jsonrpc的泛化调用同时存在,那么服务端必须能够同时对这两种典型的调用的方式进行兼容。不用担心,jsonrpc做到了和spring的web框架可以完美集成,比如服务端使用jsonrpc与springboot进行集成。
这里解释一下什么是jsonrpc的泛化调用?简单说,就是对jsonrpc的传输协议进行改造并进行http调用,让服务端以传统webController的方式接收请求。
那jsonrpc的标准调用又是什么?这里就不对jsonrpc的基础使用姿势进行说明,不熟悉的同学可以自己补一下相关的基础知识:https://github.com/briandilley/jsonrpc4j
jsonrpc的基本协议格式是:

具体可以看下官方文档相关协议说明:https://www.jsonrpc.org/specification
思路分析
那么,jsonrpc的泛化请求在服务端是怎么处理的?

是不是看起来跟普通的http的web请求没啥两样?前边说过,服务端我们是springboot+jsonrpc的框架,所以会由DispatcherServlet的doDispatch方法为入口。关键代码如下:
mappedHandler = getHandler(processedRequest);
首先,DispatcherServlet里getHandler方法就可以通过request对象从以下handlerMappings中找到合适的handler。代码如下:
/** * Return the HandlerExecutionChain for this request. * <p>Tries all handler mappings in order. * @param request current HTTP request * @return the HandlerExecutionChain, or {@code null} if no handler could be found */@Nullableprotected HandlerExecutionChain getHandler(HttpServletRequest request) throws Exception { if (this.handlerMappings != null) { for (HandlerMapping mapping : this.handlerMappings) { HandlerExecutionChain handler = mapping.getHandler(request); if (handler != null) { return handler; } } } return null;}

比如这里找到的就是具体的Controller的目标调用method,同时这里匹配到的是RequestMappingHandlerMapping:

但是对于jsonrpc的标准调用这里有了变化。你会发现这里匹配到的是BeanNameHandlerMapping,得到的handler是JsonServiceExporter。

JsonServiceExporter是jsonrpc的类,继承了AbstractJsonServiceExporter,实现了org.springframework.web.HttpRequestHandler。JsonServiceExporter是被spring容器实例化的时候调用AbstractJsonServiceExporter的afterProperties方法来完成jsonrpcServer的创建。代码如下:
-
• JsonServiceExporter
public class JsonServiceExporter extends AbstractJsonServiceExporter implements HttpRequestHandler { private JsonRpcServer jsonRpcServer; /** * {@inheritDoc} */ @Override protected void exportService() { jsonRpcServer = getJsonRpcServer(); } /** * {@inheritDoc} */ public void handleRequest(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException { jsonRpcServer.handle(request, response); response.getOutputStream().flush(); }}
-
• AbstractJsonServiceExporter:
abstract class AbstractJsonServiceExporter extends RemoteExporter implements InitializingBean, ApplicationContextAware { public void afterPropertiesSet() throws Exception { ... jsonRpcServer = new JsonRpcServer(objectMapper, null == getServiceInterface() ? getService() : getProxyForService(), getServiceInterface()); ..... } .....}
然后,根据handler查找HandlerAdapter,关键代码如下:
HandlerAdapter ha = getHandlerAdapter(mappedHandler.getHandler());
具体如下:
/** * Return the HandlerAdapter for this handler object. * @param handler the handler object to find an adapter for * @throws ServletException if no HandlerAdapter can be found for the handler. This is a fatal error. */protected HandlerAdapter getHandlerAdapter(Object handler) throws ServletException { if (this.handlerAdapters != null) { for (HandlerAdapter adapter : this.handlerAdapters) { if (adapter.supports(handler)) { return adapter; } } } throw new ServletException("No adapter for handler [" + handler + "]: The DispatcherServlet configuration needs to include a HandlerAdapter that supports this handler");}
这里的handlerAdapters是:

这里handler最终找到的是RequestMappingHandlerAdapter。但同样如果是jsonrpc的标准调用,这里就又不一样了。由于JsonServiceExporter实现了HttpRequestHandler接口,所以这里支持的适配器就是HttpRequestHandlerAdapter。
public class JsonServiceExporter extends AbstractJsonServiceExporter implements HttpRequestHandler{......}

然后,就是执行具体的方法返回modeAndView视图了。关键代码:
mv = ha.handle(processedRequest, response, mappedHandler.getHandler());
但RequestMappingHandlerAdapter也同样没有实现这个抽象的Abstract
HandlerMethodAdapter的handle方法,使用抽象类中的handle方法。
/** * This implementation expects the handler to be an {@link HandlerMethod}. */@Override@Nullablepublic final ModelAndView handle(HttpServletRequest request, HttpServletResponse response, Object handler) throws Exception { return handleInternal(request, response, (HandlerMethod) handler);}
最终执行到业务Controller中的方法。不过jsonrpc的标准调用返回的适配器是HttpRequestHandlerAdapter,自然也就是执行其hanle方法了。
package org.springframework.web.servlet.mvc;import javax.servlet.http.HttpServletRequest;import javax.servlet.http.HttpServletResponse;import org.springframework.lang.Nullable;import org.springframework.web.HttpRequestHandler;import org.springframework.web.servlet.HandlerAdapter;import org.springframework.web.servlet.ModelAndView;/** * Adapter to use the plain {@link org.springframework.web.HttpRequestHandler} * interface with the generic {@link org.springframework.web.servlet.DispatcherServlet}. * Supports handlers that implement the {@link LastModified} interface. * * <p>This is an SPI class, not used directly by application code. * * @author Juergen Hoeller * @since 2.0 * @see org.springframework.web.servlet.DispatcherServlet * @see org.springframework.web.HttpRequestHandler * @see LastModified * @see SimpleControllerHandlerAdapter */public class HttpRequestHandlerAdapter implements HandlerAdapter { @Override public boolean supports(Object handler) { return (handler instanceof HttpRequestHandler); } @Override @Nullable public ModelAndView handle(HttpServletRequest request, HttpServletResponse response, Object handler) throws Exception { ((HttpRequestHandler) handler).handleRequest(request, response); return null; } @Override public long getLastModified(HttpServletRequest request, Object handler) { if (handler instanceof LastModified) { return ((LastModified) handler).getLastModified(request); } return -1L; }}
这里hanle传进来的handler也就是JsonServiceExporter,也就是说最终会执行其hanleRequest方法。

最后在jsonRpcServer中进行一系列的反射调用,执行到最后的标注有@AutoJsonRpcServiceImpl的Service方法上。到此,基于jsonrpc的标准调用和泛化调用源码执行流程就分析完毕了!
欢迎大家提出自己的想法和问题!留言区等你!
夜雨聆风
