反射工具类 MetaObject
我们一般获取属性,会根据属性名进行getter和setter方法
Personnel personnel = new Personnel();
// 假如知道有一个属性叫做id
personnel.setId("id");
String id = personnel.getId();
对于我们正常的反射,我们可以进行以下操作,来进行getter方法
Object personnel = new Personnel();
// 假设我们知道有一个属性叫做id
Method getId = personnel.getClass().getDeclaredMethod("getId");
Object invoke = getId.invoke(personnel);
这种写法当然可以,但是显得相当臃肿,并且不能进行复用,我们先看看MyBatis给我们的方法。
Object personnel = new Personnel();
// 装饰器模式
Configuration configuration = new Configuration();
MetaObject metaObject = configuration.newMetaObejct(personnel);
// setter方法
metaObject.setValue("id","1");
// getter方法
metaObject.getValue("id");
是不是非常方便,并且他的功能不止于此。
// 假设Personnel包含一个属性为User user;
metaObject.setValue("user.id","1");
// 这也是被允许的
//假设Personnel包含一个grades属性的List数组
metaObject.setValue("grades",new ArrayList<>());
我们来看一下metaObject的具体实现
对于一个comments[0].user.name,会循环递归,直到获取最后一个值
其中,我们看到getValue需要进入分词器PropertyTokenizer
。我们可以学习一下分词器的代码。
其主要实现了迭代器,来进行判断是否有children,在运用方面进行递归,就可以循环遍历传进来的string。(自己设计的话,很难想到用实现迭代器的方式)
怎样判断是否是集合?
看迭代器里的index是否不为空,不为空则代表是集合的下标
我们可以看一下BeanWrapper的代码
下来就是根据集合去get,或者通过反射去获取属性名,以下略过。