前言
之前有一篇文章讲了Java的Gson、FastJson等解析json常用类,与Python的json模块比较,繁琐之处是要定义各种实体类。那么,Java中有没有自动定义实体类的方法呢?
数据接入是我在大数据工作中的一部分,定长、csv、json是比较常见的几种数据格式。通常我都是使用Flume来完成数据的接入,根据对端数据源配置source,在数据源配置Interceptor(拦截器),将channel设置为kafka(通常是memory,为了流计算所以放在kafka),sink设置成文件等待后续调度入库。
Flume提供的的source、channel、sink基本可以覆盖日常需求,通过conf配置就可以轻松使用。而Interceptor很多时候都需要自己开发打包,放到Flume的lib中,然后在conf配置中绑定在source中,这样就能在进入channel之前对数据进行处理。
随着接入的Json数据越来越多,每接入一种格式的json,都要定义一个实体类,然后定义一个Interceptor,来将Json解析成CSV。
后来有一天就想着,能不能开发一个适配性Json的Interceptor,在配置文件中配置字段名称,就自动生成实体类,然后自动在Gson中引入这个实体类,对json数据进行解析。
javassist
说起自动生成类,就想起了我在2017年自学Java时学到的javassist类。
javassist提供了动态生成class的功能,接下来就看看如何使用javassist来创建一个类。
<dependency>
<groupId>org.javassist</groupId>
<artifactId>javassist</artifactId>
<version>3.29.2-GA</version>
</dependency>
CtClass
既然是创建class,那么一定会有个类,来表示正在构建的class对象,这样才能对class进行添加字段和方法等操作,这个类就是CtClass,即compile-time class,编译时class文件。
接着就是看看如何都创建CtClass对象。
从注释中看,CtClass是从ClassPool中获取。
ClassPool
ClassPool就是存放被JVM加载后class的容器,我们通常使用ClassPool.getDefault() 来获取CLASSPATH的class。
ClassPool pool = ClassPool.getDefault();
CtClass ctClass = pool.get("java.lang.String");
System.out.println(ctClass);
我们来获取String的CtClass。