批注接口 DsonSerializable


@Retention(RUNTIME) @Target(TYPE) public @interface DsonSerializable
用于标注一个类的对象可序列化为Dson文档结构

注解处理器

对于带有该注解的类: 1. 如果是枚举,必须实现EnumLite并提供静态非private的forNumber(int)方法 - EnumUtils.mapping(EnumLite[])。 2. 如果是普通类,必须提供非私有无参构造方法,或提供非私有的DsonObjectReader的单参构造方法。 3. 对于普通类,所有托管给生成代码读的字段,必须提供setter或直接写权限。 4. 对于普通类,所有托管给生成代码写的字段,必须提供getter或直接读权限。 5. 如果字段通过DsonProperty.readProxy()指定了读代理,则不要求setter权限 6. 如果字段通过DsonProperty.writeProxy()指定了写代理,则不要求getter权限

普通类钩子方法: 1. 如果类提供了静态的newInstance(DsonObjectReader, TypeInfo)方法,将自动调用 -- 优先级高于构造方法,可处理final字段。 2. 如果类提供了非私有的ClassName(DsonObjectReader, TypeInfo)的构造方法,将自动调用 -- 该方法可用于final和忽略字段。 3. 如果类提供了非私有的afterDecode(ConverterOptions)方法,且在options中启用,则自动调用 -- 通常用于数据转换,或构建缓存字段。 4. 如果类提供了非私有的beforeEncode(ConverterOptions)方法,且在options中启用,则自动调用 -- 通常用于数据转换。 5. 如果类提供了非私有的readObject(DsonObjectReader)方法,将自动调用 -- 该方法可用于忽略字段。 6. 如果类提供了非私有的writeObject(DsonObjectWriter)方法,将自动调用 -- 该方法可用于final和忽略字段。 7. 如果是通过DsonCodecLinkerBean配置的类,这些方法都需要转换为静态方法。

 
      public void beforeEncode(ConverterOptions options){}
      public void writeObject(DsonObjectWriter writer){}

      public static Bean newInstance(DsonObjectReader reader, TypeInfo typeInfo){}
      public void readObject(DsonObjectReader reader){}
      public void afterDecode(ConverterOptions options){}

      public void writeField1(DsonObjectWriter writer, String dsonName){}
      public void readField1(DsonObjectReader reader, String dsonName){}
 
ps:如果要更好的支持泛型,似乎应该将TypeInfo传入...

序列化的字段

1. 默认序列化public和或包含public getter的字段;默认忽略transient修饰或DsonIgnore注解的字段。 2. DsonIgnore也可以用于将transient字段加入编解码。 3. 如果你提供了WriteObjet和ReadObject方法,你可以在其中写入忽略字段。

多态字段

1. 如果对象的运行时类型存在于DsonCodecRegistry中,则总是可以精确解析,因此不需要特殊处理。 2. 否则用户需要指定实现类或读代理实现精确解析,请查看DsonProperty注解。

final字段

详见:

读写忽略字段

用户可以通过构造解码器和写对象方法实现。

扩展

Q: 是否可以不使用注解,也能序列化? A: 如果不使用注解,需要手动实现DsonCodec,并将其添加到注册表中。 (也可以加入到Scanner的扫描路径)

一些建议

1. 一般而言,建议使用该注解并遵循相关规范,由注解处理器生成的类负责解析,而不是手动实现DsonCodec。 2. 并不建议都实现为javabean格式。 *

辅助类类名

生成的辅助类为XXXCodec
作者:
wjybxx date 2023/3/31
  • 可选元素概要

    可选元素
    修饰符和类型
    可选元素
    说明
    Class<? extends Annotation>[]
    为生成的文件添加的注解 比如:可以添加DsonCodecScanIgnore以使得生成的代码在扫描Codec时被忽略。
    序列化时的类型名。
    单例对象获取实例的静态方法 1.如果该属性不为空,则表示对象是单例;序列化时不写入字段,反序列化时直接返回单例。
    声明不需要自动序列化的字段(自身或超类的) 注意:skip仅仅表示不自动读,被跳过的字段仍然会占用字段编号和name!
    序列化时的缩进格式
  • 元素详细资料

    • className

      String[] className
      序列化时的类型名。 1.第一个元素为默认名。 2.支持多个以支持别名。 3.APT不解析该字段 - Codec无需持有该信息。

      Q:为什么是个数组? A:这允许定义别名,以支持简写 -- 比如:'@Vector3' 可以简写为 '@V3';而数字id通常不需要该支持。

      默认值:
      {}
    • style

      序列化时的缩进格式
      默认值:
      INDENT
    • singleton

      String singleton
      单例对象获取实例的静态方法 1.如果该属性不为空,则表示对象是单例;序列化时不写入字段,反序列化时直接返回单例。 2.用户可以通过实现Codec实现单例和特殊多例的解析,这里只是对常见情况提供快捷方式。 3.如果是由DsonCodecLinkerBean配置的类,则指向配置类中的静态方法。
      默认值:
      ""
    • skipFields

      String[] skipFields
      声明不需要自动序列化的字段(自身或超类的) 注意:skip仅仅表示不自动读,被跳过的字段仍然会占用字段编号和name!

      该属性主要用户处理继承得来的不能直接序列化的字段,以避免编译时检查不通过(无法自动序列化)。 跳过这些字段后,你可以在解析构造方法、readObject、writeObject方法中处理。

       
         skipFields = {
             size,
             HashMap.size, // 外部类或内部类无命名冲突时,可简写
             java.util.HashMap.size, // 外部类名冲突时使用全限定名
             java.util.Map.Entry.key // 内部类名冲突时使用全限定名
         }
       
       
      1. 如果fieldName不包含点号,则认为是FieldName格式,即只通过字段名定位。 2. 如果fieldName包含1个点号,则认为是ClassSimpleName.FieldName格式,即通过类的简单名定位。 3. 如果fieldName包含多个点号,则认为是ClassCanonicalName.FieldName格式,即通过类的全限定名定位(内部类也使用点号分割)。
      默认值:
      {}
    • annotations

      Class<? extends Annotation>[] annotations
      为生成的文件添加的注解 比如:可以添加DsonCodecScanIgnore以使得生成的代码在扫描Codec时被忽略。
      默认值:
      {}