Hessian源码浅析-HessianSkeleton
Hessian服务端核心对象HessianSkeleton 主要做两件事
1.把客户端请求的流反序列化 得到 对应的方法名称 参数
2. 服务类(service)对应方法执行完成 把结果序列化到输出流
hessian服务端暴露服务是通过HessianServlet
public class HessianServlet extends GenericServlet { }
HessianServlet 的init方法主要初始化服务类(service) 和HessianSkeleton 每一个服务类对应一个HessianSkeleton 在HessianSkeleton中持有业务类的引用
public void init(ServletConfig config) throws ServletException { super.init(config); //web.xml中home-class,service-class配置服务的实现类 if (_homeImpl != null) { } else if (getInitParameter("home-class") != null) { String className = getInitParameter("home-class"); Class homeClass = loadClass(className); _homeImpl = homeClass.newInstance(); init(_homeImpl); } else if (getInitParameter("service-class") != null) { String className = getInitParameter("service-class"); Class homeClass = loadClass(className); _homeImpl = homeClass.newInstance(); init(_homeImpl); } else { if (getClass().equals(HessianServlet.class)) throw new ServletException( "server must extend HessianServlet"); _homeImpl = this; } //web.xml配置的 服务类实现接口 if (_homeAPI != null) { } else if (getInitParameter("home-api") != null) { String className = getInitParameter("home-api"); _homeAPI = loadClass(className); } else if (getInitParameter("api-class") != null) { String className = getInitParameter("api-class"); _homeAPI = loadClass(className); } else if (_homeImpl != null) { //如果没有配置服务实现类的接口 递归 找到服务类最顶层的接口 _homeAPI = findRemoteAPI(_homeImpl.getClass()); if (_homeAPI == null) _homeAPI = _homeImpl.getClass(); } //TODO _homeSkeleton = new HessianSkeleton(_homeImpl, _homeAPI); }
service方法
public void service(ServletRequest request, ServletResponse response) throws IOException, ServletException { HttpServletRequest req = (HttpServletRequest) request; HttpServletResponse res = (HttpServletResponse) response; //必须是post方式 if (!req.getMethod().equals("POST")) { res.setStatus(500, "Hessian Requires POST"); PrintWriter out = res.getWriter(); res.setContentType("text/html"); out.println("<h1>Hessian Requires POST</h1>"); return; } String serviceId = req.getPathInfo(); String objectId = req.getParameter("id"); if (objectId == null) objectId = req.getParameter("ejbid"); //保存到ThreadLocal中 ServiceContext.begin(req, serviceId, objectId); try { InputStream is = request.getInputStream(); OutputStream os = response.getOutputStream(); response.setContentType("application/x-hessian"); SerializerFactory serializerFactory = getSerializerFactory(); //交给HessianSkeleton invoke方法处理 invoke(is, os, objectId, serializerFactory); } finally { ServiceContext.end(); } }
HessianSkeleton invoke方法核心代码
public void invoke(Object service, AbstractHessianInput in, AbstractHessianOutput out) throws Exception { //..略 //反序列化 获得方法名称 String methodName = in.readMethod(); int argLength = in.readMethodArgLength(); Method method; //_methodMap中获得对应的方法 method = getMethod(methodName + "__" + argLength); // ..略 Class<?> []args = method.getParameterTypes(); //获得方法参数 Object []values = new Object[args.length]; for (int i = 0; i < args.length; i++) { // XXX: needs Marshal object values[i] = in.readObject(args[i]); } Object result = null; try { result = method.invoke(service, values); } catch (Exception e) { //...略 return; } in.completeCall(); // AbstractHessianOutput 序列化方法返回值 out.writeReply(result); out.close(); }
Andy_能力越到责任越大