Flink使用POJO提高处理效率和代码可读性

根据Flink文档Flink 的 TypeInformation 类介绍:

POJOs 是特别有趣的,因为他们支持复杂类型的创建以及在键的定义中直接使用字段名: dataSet.join(another).where("name").equalTo("personName") 它们对运行时也是透明的,并且可以由 Flink 非常高效地处理。

在Flink中使用POJO有利于提高处理效率,并且能够提高代码可读性。

什么样的类才能当做POJO?定义了一个类,它是否被Flink当做POJO了呢?

  1. 什么样的类才能当做POJO?

这部分在官方文档中有介绍:

①该类是公有的 (public) 和独立的(没有非静态内部类)

②该类拥有公有的无参构造器

③类(以及所有超类)中的所有非静态、非 transient 字段都是公有的(非 final 的), 或者具有遵循 Java bean 对于 getter 和 setter 命名规则的公有 getter 和 setter 方法。

上面的三条看不懂?往下看

  1. 创建了一个类,它是否被Flink当做POJO?

最简单的就是实例化一个对象,放到Flink中运行一下,看Flink怎么说。

StreamExecutionEnvironment env = StreamExecutionEnvironment.getExecutionEnvironment();
env.setStreamTimeCharacteristic(TimeCharacteristic.EventTime);
env.enableCheckpointing(1000);
final MyPOJOClass whiteListAlarm = new MyPOJOClass();
final DataStreamSource source = env.fromElements(MyPOJOClass);
final DataStream map = source.map((MapFunction) value -> value.toString());
map.print();
env.execute();

把日志设置为INFO等级,如果这个类不能被当做POJO,日志中会有对应的描述。在日志中搜索'pojo'就能看到,如果没有搜索到,那么恭喜你的类是一个POJO。

  1. Flink是如何判断一个类是否为POJO的?

请看源码org.apache.flink.api.java.typeutils.TypeExtractor.analyzePojo方法,主要做了如下验证:

  • 类是否为public
  • 类是否有field(个人理解:这个类是不是用来存储数据的)
  • 每个field是否都是符合POJO要求的(参看文档或者源码方法isValidPojoField
  • 是否有自定义的序列化、反序列化方法(是否重写了readObjectwriteObject)
  • 是否有public的空构造方法(如果没有定义构造方法编译时会自动添加public的空构造方法,如果定义了非空参数的沟构造方法,要显式的定义一个空参数的public构造方法)
  1. 答疑

问:我的Class继承了自另一个抽象类,是否为POJO?

答:如果抽象类和继承后的类都满足那就是POJO

问:我在Pojo中定义了一些方法,它还是POJO吗?

答:是

问:我的Pojo实现了一个接口,它还是POJO吗?

答:是的

方法什么的在序列化的时候是不会被序列化的,它们被存储在一个公共的内存区,序列化的是field,因此每个field是否符合POJO要求(是否有public的getter、setter)很重要,反序列化时需要先构造一个对象所以需要一个默认的public构造方法(空参数)

你可能感兴趣的:(Flink使用POJO提高处理效率和代码可读性)