APIJSON(四:AbstractObjectParser源码阅读(1))
2021SC@SDUSC
1.类名
首先观察一下类名
public abstract class AbstractObjectParser implements ObjectParser
可以发现这是一个抽象类,并继承了一个接口。
(1)抽象类相关知识
1、用abstract关键字来表达的类,其表达形式为:(public)abstract class 类名{}
2、抽象类不能被实例化,也就是说我们没法直接new 一个抽象类。抽象类本身就代表了一个类型,无法
确定为一个具体的对象,所以不能实例化就合乎情理了,只能有它的继承类实例化。
3、抽象类虽然不能被实例化,但有自己的构造方法。(当然如果我们不写,编译器会自动默认一个无参构造方法)。
4、抽象类与接口(interface)有很大的不同之处,接口中不能有实例方法去实现业务逻辑,而抽象类
中可以有实例方法,并实现业务逻辑,比如我们可以在抽象类中创建和销毁一个线程池。
抽象类有什么好处呢?
1、由于抽象类不能被实例化,最大的好处就是通过方法的覆盖来实现多态的属性。也就是运行期绑定
2、抽象类将事物的共性的东西提取出来,由子类继承去实现,代码易扩展、易维护。
(2)接口相关知识
注意到抽象类AbstractObjectParser是继承了一个接口的
![](/qrcode.jpg)
抽象类 | 接口 |
---|---|
使用关键字abstract修饰 | 使用关键字interface修饰 |
使用关键字extends实现继承,可以只实现一部分方法,一部分不实现,或者不实现也可以 | implements来实现接口,实现接口必须实现里面都有的方法,接口支持多继承 |
抽象类里面的方法可以是空实现,可以默认实现,但是必须要带{} | 接口里面的方法都没有实现体,也就是{} |
抽象类中可以有具体的方法以及属性,也可以有静态代码块,静态成员变量 | 接口里面不能有普通成员变量,必须都是不可变的final成员变量,而且所有的成员变量都必须是public |
抽象类里面的方法可以是public,protect,private | 接口的方法只能是public或者无修饰符,所有的private修饰都是会报错的 |
如果有改动,添加新的方法,可以直接在抽象类中实现默认的即可,也可以在实现类中实现 | 接口增加新方法必须在接口中声明,然后在实现类中进行实现 |
抽象类不能直接创建对象 | 接口也不能直接创建对象 ,可以赋予实现类的对象 |
抽象类可以有main方法,而且我们可以直接运行,抽象类也可以有构造器 | 接口不能有main方法,接口不能有构造器 |
(3)接口ObjectParser
public interface ObjectParser {
String getParentPath();
ObjectParser setParentPath(String parentPath);
ObjectParser parse(String name, boolean isReuse) throws Exception;
public JSONObject parseResponse(RequestMethod method, String table, String alias, JSONObject request, List<Join> joinList, boolean isProcedure) throws Exception;
public JSONObject parseResponse(SQLConfig config, boolean isProcedure) throws Exception;
boolean onParse(@NotNull String key, @NotNull Object value) throws Exception;
JSON onChildParse(int index, String key, JSONObject value) throws Exception;
Object onReferenceParse(@NotNull String path);
void onPUTArrayParse(@NotNull String key, @NotNull JSONArray array) throws Exception;
void onTableArrayParse(@NotNull String key, @NotNull JSONArray array) throws Exception;
ObjectParser setSQLConfig() throws Exception;
ObjectParser setSQLConfig(int count, int page, int position) throws Exception;
ObjectParser executeSQL() throws Exception;
JSONObject onSQLExecute() throws Exception;
JSONObject response() throws Exception;
void onFunctionResponse(String type) throws Exception;
void onChildResponse() throws Exception;
SQLConfig newSQLConfig(boolean isProcedure) throws Exception;
SQLConfig newSQLConfig(RequestMethod method, String table, String alias, JSONObject request, List<Join> joinList, boolean isProcedure) throws Exception;
void onComplete();
void recycle();
ObjectParser setMethod(RequestMethod method);
RequestMethod getMethod();
boolean isTable();
String getPath();
String getTable();
String getAlias();
SQLConfig getArrayConfig();
SQLConfig getSQLConfig();
JSONObject getResponse();
JSONObject getSqlRequest();
JSONObject getSqlReponse();
Map<String, Object> getCustomMap();
Map<String, Map<String, String>> getFunctionMap();
Map<String, JSONObject> getChildMap();
}
在这其中,抛开get和set相关成员属性的抽象方法不看(毕竟也没啥好解释的)。根据官方的注释——
parse相关的都是解析相关的。
只不过解析的内容根据输入有所差别而已。就比如说
parseResponse是调用 parser 的 sqlExecutor 来解析结果
onParse是解析普通成员
onChildParse是解析赋值引用
recycle是用来回收内存的
在接口上大多数方法只能看个大概,具体起什么作用我也暂时不知,希望能在继承其的抽象类中得到进一步的解答。
2.AbstractParser
首先我们可以看到这两行函数。
protected AbstractParser<?> parser;
public AbstractObjectParser setParser(AbstractParser<?> parser) {
this.parser = parser;
return this;
}
其中注意到创建了一个AbstractParser(范型)类的对象parser。
而此类的主要作用为将request请求解析成为JSON对象,而AbstractObjectParser类的功能也是对该对象进行解析。
3.成员变量及构造函数
接下来是一连串的成员变量的定义。
protected JSONObject request;//不用final是为了recycle
protected String parentPath;//不用final是为了recycle
protected SQLConfig arrayConfig;//不用final是为了recycle
protected boolean isSubquery;
protected final int type;
protected final String arrayTable;
protected final List<Join> joinList;
protected final boolean isTable;
protected final boolean isArrayMainTable;
protected final boolean tri;
/**
* TODO Parser内要不因为 非 TYPE_ITEM_CHILD_0 的Table 为空导致后续中断。
*/
protected final boolean drop;
咱们可以对其中的成员变量的两个陌生的类进行分析——
首先是JSONObject,点进去可以看见它是继承自com.alibaba.fastjson.JSONObject
public class JSONObject extends com.alibaba.fastjson.JSONObject
也就是说这是对这个的一定程度上的改写,抛开细节不谈,我们去看一下com.alibaba.fastjson.JSONObject
首先,介绍一下fastjson。fastjson是由alibaba开源的一套json处理器。与其他json处理器(如Gson,Jackson等)和其他的Java对象序列化反序列化方式相比,有比较明显的性能优势。
public class JSONObject extends JSON implements Map<String, Object>, Cloneable, Serializable, InvocationHandler
这个包里面最主要也是最常用的两个类是 JSON JSONObject 这两个类也都是内部使用的是final map 来实现的。构造的时候可以传入一个ordered。来确定使用LinkedHashMap还是HashMap。
JSONObject 实现了Map<String,Object> 接口。
然后是SQLConfig
![](https://gitee.com/otaku-ayi/img-store/raw/master/Typora/202110212218623.png)
这其实相当通俗易懂,就是数据库相关配置的信息(类如其名了属于是)
咱们接着往下看,就是一个AbstractObjectParser构造函数了
public AbstractObjectParser(@NotNull JSONObject request, String parentPath, SQLConfig arrayConfig
, boolean isSubquery, boolean isTable, boolean isArrayMainTable)
里面基本用到了上述的大多数成员变量,其中特别注意到request不能为空。
具体如下——
public AbstractObjectParser(@NotNull JSONObject request, String parentPath, SQLConfig arrayConfig
, boolean isSubquery, boolean isTable, boolean isArrayMainTable) throws Exception {
if (request == null) {
throw new IllegalArgumentException(TAG + ".ObjectParser request == null!!!");
}
this.request = request;
this.parentPath = parentPath;
this.arrayConfig = arrayConfig;
this.isSubquery = isSubquery;
this.type = arrayConfig == null ? 0 : arrayConfig.getType();
this.arrayTable = arrayConfig == null ? null : arrayConfig.getTable();
this.joinList = arrayConfig == null ? null : arrayConfig.getJoinList();
this.isTable = isTable; // apijson.JSONObject.isTableKey(table);
this.isArrayMainTable = isArrayMainTable; // isSubquery == false && this.isTable && this.type == SQLConfig.TYPE_ITEM_CHILD_0 && RequestMethod.isGetMethod(method, true);
// this.isReuse = isReuse; // isArrayMainTable && arrayConfig != null && arrayConfig.getPosition() > 0;
this.objectCount = 0;
this.arrayCount = 0;
boolean isEmpty = request.isEmpty();//empty有效 User:{}
if (isEmpty) {
this.tri = false;
this.drop = false;
}
else {
this.tri = request.getBooleanValue(KEY_TRY);
this.drop = request.getBooleanValue(KEY_DROP);
request.remove(KEY_TRY);
request.remove(KEY_DROP);
}
}