KVTypeInfo是一个类。
这个类的作用是解析其他被KVIndex注解后的类,获取索引信息。
类一开始定义了内部存储的数据。
public class KVTypeInfo {
private final Class> type; // 解析的到底是哪个类?
private final Map indices; // 索引信息放到了indices里面
private final Map accessors; // 工具,用来访问某个类的某个字段的工具
读一下构造函数
public KVTypeInfo(Class> type) {
// 构造函数传入一个参数就是,你要去解析的那个类
this.type = type;
this.accessors = new HashMap<>();
this.indices = new HashMap<>();
// 遍历这个类的所有字段
for (Field f : type.getDeclaredFields()) {
// 取出这个字段的KVIndex注解
KVIndex idx = f.getAnnotation(KVIndex.class);
// 如果这个字段有用KVIndex注解过,就...
if (idx != null) {
// 做检查,不知道做什么检查
checkIndex(idx, indices);
// 设置f这个字段为可以通过反射来访问字段的值。
f.setAccessible(true);
// 然后将索引的名字,就是默认为__main__的那个东东,作为key, KVIndex注解做为value,存储到hashmap中去
// 感觉这一句跟上面这句毛关系都没有
indices.put(idx.value(), idx);
// 那这里又重复设置f字段反射可访问,是个什么意思?
f.setAccessible(true);
// 然后将一个字段访问器设置到了访问器hashmap中,key也是那个索引名字
accessors.put(idx.value(), new FieldAccessor(f));
}
}
// 这个跟上面的字段一样,只不过是方法。遍历方法。
for (Method m : type.getDeclaredMethods()) {
// 获取注解
KVIndex idx = m.getAnnotation(KVIndex.class);
if (idx != null) {
// 检查,不是所有方法都可以用这个注解的,有要求的。
checkIndex(idx, indices);
// 方法不能带参数。感觉这个方法就像个字段一样就对了,仅仅用来获取数据的方法。
Preconditions.checkArgument(m.getParameterTypes().length == 0,
"Annotated method %s::%s should not have any parameters.", type.getName(), m.getName());
// 又是要两次设置 Accessible, 这是为什么?我想知道 ...
m.setAccessible(true);
//和字段一样的操作
indices.put(idx.value(), idx);
m.setAccessible(true);
//也是一样,FieldAccessor 和 MethodAccessor 都实现了Accessor的接口。
accessors.put(idx.value(), new MethodAccessor(m));
}
}
// 做检查
// 首先这个类起码有个主键索引,就是索引名字是__main__的索引,如果没有主键索引是不行的。
Preconditions.checkArgument(indices.containsKey(KVIndex.NATURAL_INDEX_NAME),
"No natural index defined for type %s.", type.getName());
// 主键索引不能有爸爸。
Preconditions.checkArgument(indices.get(KVIndex.NATURAL_INDEX_NAME).parent().isEmpty(),
"Natural index of %s cannot have a parent.", type.getName());
// 这个检查 如果你某个索引设置了父索引,看看父索引是否存在。
// 如果设置了父索引,父索引又没指定,就会报错。
for (KVIndex idx : indices.values()) {
if (!idx.parent().isEmpty()) {
// 看看这个索引是否有父索引,并且父索引是否存在hashmap中
KVIndex parent = indices.get(idx.parent());
Preconditions.checkArgument(parent != null,
"Cannot find parent %s of index %s.", idx.parent(), idx.value());
// 爸爸不能再有爸爸? 某个父索引自己不能是子索引。
Preconditions.checkArgument(parent.parent().isEmpty(),
"Parent index %s of index %s cannot be itself a child index.", idx.parent(), idx.value());
}
}
}
检查函数检查什么东西?
private void checkIndex(KVIndex idx, Map indices) {
// 索引名不能为null,不能为空
Preconditions.checkArgument(idx.value() != null && !idx.value().isEmpty(),
"No name provided for index in type %s.", type.getName());
// 只有主键索引名(__main__)才能 _ 开头。
Preconditions.checkArgument(
!idx.value().startsWith("_") || idx.value().equals(KVIndex.NATURAL_INDEX_NAME),
"Index name %s (in type %s) is not allowed.", idx.value(), type.getName());
// 父索引要不为空,如果不为空不能等于自己
Preconditions.checkArgument(idx.parent().isEmpty() || !idx.parent().equals(idx.value()),
"Index %s cannot be parent of itself.", idx.value());
Preconditions.checkArgument(!indices.containsKey(idx.value()),
"Duplicate index %s for type %s.", idx.value(), type.getName());
}