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();
  }

posted on 2012-05-11 17:19  YangJin  阅读(332)  评论(0编辑  收藏  举报