HessianProxyFactory是HessianProxy的工厂类,其通过HessianProxy来生成代理类。

如下面代码:

HessianProxyFactory factory = new HessianProxyFactory();
HelloService helloService = (HelloService) factory.create(HelloService.class, url);
System.out.println(helloService.helloWorld("jimmy"));

HessianProxyFactory的create函数如下:

public Object create(Class api, String urlName)
    throws MalformedURLException
  {
    return create(api, urlName, _loader);
  }
public Object create(Class<?> api, String urlName, ClassLoader loader)
    throws MalformedURLException
  {
    URL url = new URL(urlName);

    return create(api, url, loader);
  }

create函数的最终实现是:

public Object create(Class<?> api, URL url, ClassLoader loader)
  {
    if (api == null)
      throw new NullPointerException("api must not be null for HessianProxyFactory.create()");
    InvocationHandler handler = null;

    handler = new HessianProxy(url, this, api);

    return Proxy.newProxyInstance(loader,
                                  new Class[] { api,
                                                HessianRemoteObject.class },
                                  handler);
  }

由上面代码段我们可以看到,HessianProxyFactory的create函数最终是创建了一个HessianProxy代理类的目标类。

HessianProxyFactory的作用就是通过代理类HessianProxy来生成目标类。

HessianProxyFactory源码如下:

public class HessianProxyFactory implements ServiceProxyFactory, ObjectFactory {
  protected static Logger log
    = Logger.getLogger(HessianProxyFactory.class.getName());

  private final ClassLoader _loader;

  private SerializerFactory _serializerFactory;

  private HessianConnectionFactory _connFactory;

  private HessianRemoteResolver _resolver;

  private String _user;
  private String _password;
  private String _basicAuth;

  private boolean _isOverloadEnabled = false;

  private boolean _isHessian2Reply = true;
  private boolean _isHessian2Request = false;

  private boolean _isChunkedPost = true;
  private boolean _isDebug = false;

  private long _readTimeout = -1;
  private long _connectTimeout = -1;

  public HessianProxyFactory()
  {
    this(Thread.currentThread().getContextClassLoader());
  }
  public HessianProxyFactory(ClassLoader loader)
  {
    _loader = loader;
    _resolver = new HessianProxyResolver(this);
  }

  public void setUser(String user)
  {
    _user = user;
    _basicAuth = null;
  }

  public void setPassword(String password)
  {
    _password = password;
    _basicAuth = null;
  }

  public String getBasicAuth()
  {
    if (_basicAuth != null)
      return _basicAuth;

    else if (_user != null && _password != null)
      return "Basic " + base64(_user + ":" + _password);

    else
      return null;
  }
  public void setConnectionFactory(HessianConnectionFactory factory)
  {
    _connFactory = factory;
  }

  public HessianConnectionFactory getConnectionFactory()
  {
    if (_connFactory == null) {
      _connFactory = createHessianConnectionFactory();
      _connFactory.setHessianProxyFactory(this);
    }

    return _connFactory;
  }

  public void setDebug(boolean isDebug)
  {
    _isDebug = isDebug;
  }
  public boolean isDebug()
  {
    return _isDebug;
  }

  /**
   * Returns true if overloaded methods are allowed (using mangling)
   */
  public boolean isOverloadEnabled()
  {
    return _isOverloadEnabled;
  }

  /**
   * set true if overloaded methods are allowed (using mangling)
   */
  public void setOverloadEnabled(boolean isOverloadEnabled)
  {
    _isOverloadEnabled = isOverloadEnabled;
  }

  /**
   * Set true if should use chunked encoding on the request.
   */
  public void setChunkedPost(boolean isChunked)
  {
    _isChunkedPost = isChunked;
  }

  /**
   * Set true if should use chunked encoding on the request.
   */
  public boolean isChunkedPost()
  {
    return _isChunkedPost;
  }

  /**
   * The socket timeout on requests in milliseconds.
   */
  public long getReadTimeout()
  {
    return _readTimeout;
  }

  /**
   * The socket timeout on requests in milliseconds.
   */
  public void setReadTimeout(long timeout)
  {
    _readTimeout = timeout;
  }

  /**
   * The socket connection timeout in milliseconds.
   */
  public long getConnectTimeout()
  {
    return _connectTimeout;
  }

  /**
   * The socket connect timeout in milliseconds.
   */
  public void setConnectTimeout(long timeout)
  {
    _connectTimeout = timeout;
  }

  /**
   * True if the proxy can read Hessian 2 responses.
   */
  public void setHessian2Reply(boolean isHessian2)
  {
    _isHessian2Reply = isHessian2;
  }

  /**
   * True if the proxy should send Hessian 2 requests.
   */
  public void setHessian2Request(boolean isHessian2)
  {
    _isHessian2Request = isHessian2;

    if (isHessian2)
      _isHessian2Reply = true;
  }

  /**
   * Returns the remote resolver.
   */
  public HessianRemoteResolver getRemoteResolver()
  {
    return _resolver;
  }

  /**
   * Sets the serializer factory.
   */
  public void setSerializerFactory(SerializerFactory factory)
  {
    _serializerFactory = factory;
  }

  /**
   * Gets the serializer factory.
   */
  public SerializerFactory getSerializerFactory()
  {
    if (_serializerFactory == null)
      _serializerFactory = new SerializerFactory(_loader);

    return _serializerFactory;
  }

  protected HessianConnectionFactory createHessianConnectionFactory()
  {
    String className
      = System.getProperty(HessianConnectionFactory.class.getName());

    HessianConnectionFactory factory = null;

    try {
      if (className != null) {
        ClassLoader loader = Thread.currentThread().getContextClassLoader();

        Class<?> cl = Class.forName(className, false, loader);

        factory = (HessianConnectionFactory) cl.newInstance();

        return factory;
      }
    } catch (Exception e) {
      throw new RuntimeException(e);
    }

    return new HessianURLConnectionFactory();
  }

  public Object create(String url)
    throws MalformedURLException, ClassNotFoundException
  {
    HessianMetaInfoAPI metaInfo;

    metaInfo = (HessianMetaInfoAPI) create(HessianMetaInfoAPI.class, url);

    String apiClassName =
      (String) metaInfo._hessian_getAttribute("java.api.class");

    if (apiClassName == null)
      throw new HessianRuntimeException(url + " has an unknown api.");

    Class<?> apiClass = Class.forName(apiClassName, false, _loader);

    return create(apiClass, url);
  }
  public Object create(Class api, String urlName)
    throws MalformedURLException
  {
    return create(api, urlName, _loader);
  }

  public Object create(Class<?> api, String urlName, ClassLoader loader)
    throws MalformedURLException
  {
    URL url = new URL(urlName);

    return create(api, url, loader);
  }

  public Object create(Class<?> api, URL url, ClassLoader loader)
  {
    if (api == null)
      throw new NullPointerException("api must not be null for HessianProxyFactory.create()");
    InvocationHandler handler = null;

    handler = new HessianProxy(url, this, api);

    return Proxy.newProxyInstance(loader,
                                  new Class[] { api,
                                                HessianRemoteObject.class },
                                  handler);
  }

  public AbstractHessianInput getHessianInput(InputStream is)
  {
    return getHessian2Input(is);
  }

  public AbstractHessianInput getHessian1Input(InputStream is)
  {
    AbstractHessianInput in;

    if (_isDebug)
      is = new HessianDebugInputStream(is, new PrintWriter(System.out));

    in = new HessianInput(is);

    in.setRemoteResolver(getRemoteResolver());

    in.setSerializerFactory(getSerializerFactory());

    return in;
  }

  public AbstractHessianInput getHessian2Input(InputStream is)
  {
    AbstractHessianInput in;

    if (_isDebug)
      is = new HessianDebugInputStream(is, new PrintWriter(System.out));

    in = new Hessian2Input(is);

    in.setRemoteResolver(getRemoteResolver());

    in.setSerializerFactory(getSerializerFactory());

    return in;
  }

  public AbstractHessianOutput getHessianOutput(OutputStream os)
  {
    AbstractHessianOutput out;

    if (_isHessian2Request)
      out = new Hessian2Output(os);
    else {
      HessianOutput out1 = new HessianOutput(os);
      out = out1;

      if (_isHessian2Reply)
        out1.setVersion(2);
    }

    out.setSerializerFactory(getSerializerFactory());

    return out;
  }
  public Object getObjectInstance(Object obj, Name name,
                                  Context nameCtx, Hashtable<?,?> environment)
    throws Exception
  {
    Reference ref = (Reference) obj;

    String api = null;
    String url = null;

    for (int i = 0; i < ref.size(); i++) {
      RefAddr addr = ref.get(i);

      String type = addr.getType();
      String value = (String) addr.getContent();

      if (type.equals("type"))
        api = value;
      else if (type.equals("url"))
        url = value;
      else if (type.equals("user"))
        setUser(value);
      else if (type.equals("password"))
        setPassword(value);
    }

    if (url == null)
      throw new NamingException("`url' must be configured for HessianProxyFactory.");
    // XXX: could use meta protocol to grab this
    if (api == null)
      throw new NamingException("`type' must be configured for HessianProxyFactory.");

    Class apiClass = Class.forName(api, false, _loader);

    return create(apiClass, url);
  }
  private String base64(String value)
  {
    StringBuffer cb = new StringBuffer();

    int i = 0;
    for (i = 0; i + 2 < value.length(); i += 3) {
      long chunk = (int) value.charAt(i);
      chunk = (chunk << 8) + (int) value.charAt(i + 1);
      chunk = (chunk << 8) + (int) value.charAt(i + 2);

      cb.append(encode(chunk >> 18));
      cb.append(encode(chunk >> 12));
      cb.append(encode(chunk >> 6));
      cb.append(encode(chunk));
    }

    if (i + 1 < value.length()) {
      long chunk = (int) value.charAt(i);
      chunk = (chunk << 8) + (int) value.charAt(i + 1);
      chunk <<= 8;

      cb.append(encode(chunk >> 18));
      cb.append(encode(chunk >> 12));
      cb.append(encode(chunk >> 6));
      cb.append('=');
    }
    else if (i < value.length()) {
      long chunk = (int) value.charAt(i);
      chunk <<= 16;

      cb.append(encode(chunk >> 18));
      cb.append(encode(chunk >> 12));
      cb.append('=');
      cb.append('=');
    }

    return cb.toString();
  }

  public static char encode(long d)
  {
    d &= 0x3f;
    if (d < 26)
      return (char) (d + 'A');
    else if (d < 52)
      return (char) (d + 'a' - 26);
    else if (d < 62)
      return (char) (d + '0' - 52);
    else if (d == 62)
      return '+';
    else
      return '/';
  }
}

Hessian源码分析--HessianProxyFactory的更多相关文章

  1. Hessian源码分析--HessianProxy

    在上一篇博客 Hessian源码分析--HessianProxyFactory 中我们了解到,客户端获得的对象其实是HessianProxy生成的目标对象,当调用目标对象的方法时,会调用Hessian ...

  2. Hessian源码分析--HessianSkeleton

    HessianSkeleton是Hessian的服务端的核心,简单总结来说:HessianSkeleton根据客户端请求的链接,获取到需要执行的接口及实现类,对客户端发送过来的二进制数据进行反序列化, ...

  3. Hessian源码分析--总体架构

    Hessian是一个轻量级的remoting onhttp工具,使用简单的方法提供了RMI的功能. 相比WebService,Hessian更简单.快捷.采用的是二进制RPC协议,因为采用的是二进制协 ...

  4. (转)hessian源码分析(一)------架构

    在计费中心的对外交互这块采用了hessian,有必要对hessian的运行机理和源码做一定的解析. 大致翻了翻源码后,发现hessian的主要结构分客户端与服务端,中间基于http传输.客户端主要做的 ...

  5. Hessian源码分析--HessianServlet

    Hessian可以通过Servlet来对外暴露服务,HessianServlet继承于HttpServlet,但这仅仅是一个外壳,使用web服务器来提供对外的Http请求,在web.xml中我们会进行 ...

  6. SURF算法与源码分析、下

    上一篇文章 SURF算法与源码分析.上 中主要分析的是SURF特征点定位的算法原理与相关OpenCV中的源码分析,这篇文章接着上篇文章对已经定位到的SURF特征点进行特征描述.这一步至关重要,这是SU ...

  7. Dubbo 源码分析 - 服务引用

    1. 简介 在上一篇文章中,我详细的分析了服务导出的原理.本篇文章我们趁热打铁,继续分析服务引用的原理.在 Dubbo 中,我们可以通过两种方式引用远程服务.第一种是使用服务直联的方式引用服务,第二种 ...

  8. 【OpenCV】SIFT原理与源码分析:关键点搜索与定位

    <SIFT原理与源码分析>系列文章索引:http://www.cnblogs.com/tianyalu/p/5467813.html 由前一步<DoG尺度空间构造>,我们得到了 ...

  9. 12.源码分析—如何为SOFARPC写一个序列化?

    SOFARPC源码解析系列: 1. 源码分析---SOFARPC可扩展的机制SPI 2. 源码分析---SOFARPC客户端服务引用 3. 源码分析---SOFARPC客户端服务调用 4. 源码分析- ...

随机推荐

  1. 好久没用IJ写Java 之 《求输入的一个数中包含奇数、偶数、零的个数》

    /** *Created by xuzili at 22:12 on 2018/4/4 */ // 以上注释使用了IntelliJ Idea的File-Settings-Editor-Live Tem ...

  2. mac下怎么删除隐藏文件比如 .Trashes文件

    U盘和移动硬盘接入Mac时会产生.Trashes,.Spotlight-V100,.fseventsd等文件 每插入Mac一次,都会检查是否有这些文件,如果没有,就会创建这些文件 特别是有时候,在文件 ...

  3. Redis Cluster集群主从方案

    本文介绍一种通过Jedis和Cluster实现Redis集群(主从)的高可用方案,该方案需要使用Jedis2.8.0(推荐),Redis3.0及以上版本(强制). 附:Redis Cluster集群主 ...

  4. js操作符+和()

    ECMA-262 描述了一组用于操作数据值的操作符,包括一元操作符.算数操作符逻辑操作符.关系操作符.赋值操作符.字符串操作符.对象操作符等.ECMAScript 操作符的与众不同之处在于,它们能够适 ...

  5. spark升级后 集成hbase-1.0.0-cdh5.4.5异常

    .具体场景如下: spark1.6  升级  spark2.2 后    分析查询hbase  数据报异常: 具体错误如下:       ERROR TableInputFormat: java.io ...

  6. KVM 时钟分析

    1. 关于GToffset: KVM的guset时钟为gc0_COUNT 其中:mfc0 gc0_count = c0_COUNT+GToffset vcpu_run 以及 vcpu_reenter的 ...

  7. 两行代码搞定Android视图扩散切换效果

    用最简单的方式来实现Android视图扩散切换效果. 一.概述 这两天时间动手撸了个视图扩散切换效果的控制器,API兼容至Android4.0,更方便我们在视图切换过程中有炫酷的过渡效果.本来是想实现 ...

  8. 2016移动端Android新技术综合预览--好文不多,这一篇就足够

    Csdn /Tamic 原文地址: http://blog.csdn.net/sk719887916/article/details/53525067 本文章6月份已完成(http://www.jia ...

  9. Zookeeper的功能以及工作原理 (转自:http://www.cnblogs.com/felixzh/p/5869212.html)

    1.ZooKeeper是什么?ZooKeeper是一个分布式的,开放源码的分布式应用程序协调服务,是Google的Chubby一个开源的实现,它是集群的管理者,监视着集群中各个节点的状态根据节点提交的 ...

  10. Dynamics CRM2016 使用web api来创建注释时的注意事项

    在使用wei api 创建注释的时候,有个字段需要注意下,就是下面图中的objectid字段,虽然它是个查找字段,但不能像普通的查找字段property@odata.bind来赋值 上代码,注意看倒数 ...