Hessian源码解析(四)

上篇博客我们说了call()方法,这次我们来展开讨论,call()方法是AbstractHessianOutput中的方法,该方法使用了模板方法设计模式,什么是模板方法设计模式?

举个例子:

我们将使用电脑分为3步。打开电脑,使用,关闭电脑

我们看看在这三步里那几步具有共性,那几步在不同的人身上有不同的体现

第一步:打开电脑,毫无疑问所有人在使用电脑前都要打开电脑

第二步:使用,不同的人使用电脑的目的是不一样的,有的人打开电脑用来办公,有的人打开电脑用来玩游戏,有的人打开电脑用来看视频,等等。。。

第三步:关闭电脑,用完电脑都会关闭

在这三步中因为一、三步具有共性所以我们可以把它们提到父类中,而第二步是不具备共性的所以将第二步放到子类中进行个性化实现

以上大概就是模板方法模式的思想

基本上所有的设计模式都和多态有紧密的联系,所以深刻的理解多态是理解设计模式的基础

  public void call(String method, Object []args)
    throws IOException
  {
    int length = args != null ? args.length : 0;
    
    startCall(method, length);
    
    for (int i = 0; i < length; i++)
      writeObject(args[i]);
    
    completeCall();
  }

我们先来看一下时序图是什么样的

上面代码对应的是时序图中的1.1.1,HessianOutput会调用SerilalizerFactory的getSerializer(Class cl)方法获取到对应的可以序列化cl对象的序列化对象,SerilalizerFactory的loadSerializer(Class<?> cl)方法会完成根据cl对象获取序列化对象的功能

让我们来看看loadSerializer方法具体实现的情况

protected Serializer loadSerializer(Class<?> cl)
    throws HessianProtocolException
  {
    Serializer serializer = null;

    for (int i = 0;
         _factories != null && i < _factories.size();
         i++) {
      AbstractSerializerFactory factory;

      factory = (AbstractSerializerFactory) _factories.get(i);

      serializer = factory.getSerializer(cl);

      if (serializer != null)
        return serializer;
    }
    //Hessian第一次获取到Class对象与序列化对象的对应关系后会将这个对应关系放到缓存中,然后每次回去缓存中查找是否有某个Class对象和序列化对象的对应关系
    //如果有该对应关系,直接返回就可以了(因为序列化对象是无状态对象,所以所有同一类型的Class对象可以共用一个序列化对象),java中的基本类型和对应的包装类
    //Hessian在初始化时就已经把对应关系放到了map里,所以基本类型对象在这里就能拿到对应的Serializer
  serializer = _contextFactory.getSerializer(cl.getName());
    //缓存中有序列化对应关系,直接返回
    if (serializer != null)
      return serializer;

    ClassLoader loader = cl.getClassLoader();

    if (loader == null)
      loader = _systemClassLoader;

    ContextSerializerFactory factory = null;

    factory = ContextSerializerFactory.create(loader);
    //如果cl对象有定制化的序列化对象则返回定制的序列化对象,举个例子
    //客户端想把一个自定义的对象Person传输到服务端,客户端可以为Person自定义一个序列化对象来做这件事情,但是自定义序列化类一定要符合Hessian的规则
    //在Hessian中自定义序列化类一定要遵守两个规则
    //1、自定义序列化类名以HessianSerializer结尾,例如Person的自定义序列化类名为PersonHessianSerializer
    //2、自定义序列化类要实现Serializer接口,并实现该接口中的writeObject()方法
   serializer = factory.getCustomSerializer(cl);
    //如果该类有自定义序列化对象返回
    if (serializer != null) {
      return serializer;
    }
    //该行代码以下都是用来判断根据cl获取对应的序列化对象,我们会重点挑出几个重点的序列化对象在单独的博客中分析
    if (HessianRemoteObject.class.isAssignableFrom(cl)) {
      return new RemoteSerializer();
    }
    else if (BurlapRemoteObject.class.isAssignableFrom(cl)) {
      return new RemoteSerializer();
    }
    else if (InetAddress.class.isAssignableFrom(cl)) {
      return InetAddressSerializer.create();
    }
    else if (JavaSerializer.getWriteReplace(cl) != null) {
      Serializer baseSerializer = getDefaultSerializer(cl);
      
      return new WriteReplaceSerializer(cl, getClassLoader(), baseSerializer);
    }
    else if (Map.class.isAssignableFrom(cl)) {
      if (_mapSerializer == null)
        _mapSerializer = new MapSerializer();

      return _mapSerializer;
    }
    else if (Collection.class.isAssignableFrom(cl)) {
      if (_collectionSerializer == null) {
        _collectionSerializer = new CollectionSerializer();
      }

      return _collectionSerializer;
    }

    else if (cl.isArray())
      return new ArraySerializer();

    else if (Throwable.class.isAssignableFrom(cl))
      return new ThrowableSerializer(cl, getClassLoader());

    else if (InputStream.class.isAssignableFrom(cl))
      return new InputStreamSerializer();

    else if (Iterator.class.isAssignableFrom(cl))
      return IteratorSerializer.create();

    else if (Calendar.class.isAssignableFrom(cl))
      return CalendarSerializer.SER;
    
    else if (Enumeration.class.isAssignableFrom(cl))
      return EnumerationSerializer.create();

    else if (Enum.class.isAssignableFrom(cl))
      return new EnumSerializer(cl);

    else if (Annotation.class.isAssignableFrom(cl))
      return new AnnotationSerializer(cl);

    return getDefaultSerializer(cl);
  }
获取到对应的序列化对象后就可以调用序列化对象的writeObject()方法将将信息写到server端

看到很多博客都写Hessian使用JavaSerializer来进行序列化的,其实在实际的应用场景中基本上都不是用JavaSerializer来做序列化的,后面的博文中也会说到这些




  • 0
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值