一、问题汇总
1.mybatis的反射工具包结构以及各个组成的作用?
|--- reflection
|--- factory
-I- ObjectFactory
--- DefaultObjectFactory
|--- invoker
-I- Invoker
--- MethodInvoker
--- SetFieldInvoker
--- GetFieldInvoker
|--- property
--- PropertyCopier
--- PropertyNamer
--- PropertyTokenizer
|--- wrapper
-I- ObjectWrapper
-A- BaseWrapper
--- BeanWrapper
--- MapWrapper
--- CollectionWrapper
-I- ObjectWrapperFactory
--- DefaultObjectWrapperFactory
--- Reflector
--- MetaClass
--- MetaObject
--- TypeParameterResolver
--- SystemMetaObject
--- ExceptionUtil
--- ReflectionException
-I- ReflectorFactory
--- DefaultReflectorFactory
factory包:
对象工厂包的作用是初始化对象实例,通过无参构造或者有参构造函数反射实例化对象,主要有create和isCollection方法,唯一实现类DefaultObjectFactory
invoker包:
invoker是反射实体Method和field的包装类,它将method包装成MethodInvoker,invoke就是执行该方法。将可写的field包装成SetFieldInvoker,invoke方法执行赋值操作,有入参,将可读的field包装成GetFieldInvoker,invoke方法执行读取变量的操作,有返回值。
property包:
这是一个属性工具包,PropertyCopier作用相当于BeanUtils.copy, PropertyNamer作用是根据set/get/is方法名获取字段名,例如:getName方法名对应的字段名为 name。 PropertyTokenizer专门用来解析 user[0].role[1].menu[0]这种类型的字符串。
wrapper包:
这是一个对象包装工具包,顶层接口为ObjectWrapper定义了常用的方法(获取get/set属性名、获取属性get/set方法、get/set属性值、构建属性MetaObject对象…)BaseWrapper代表常规的key-value对象包装,子类有BeanWrapper和MapWrapper两个,在这层加了MetaObject对象、CollectionWrapper代表数组类型的对象包装,它只有add、addAll、isCollection三个可用方法。BeanWrapper中有MetaClass类元数据对象,MapWrapper中存放的Map<String, Object> map集合。
Reflector:
类的元数据
Metaclass:
Reflector基础上的一层封装,加上了PropertyTokenizer,可以通过(user.role.menu[index])的方式来获取层级中的元数据
MetaObject:
对象的元数据
TypeParameterResolver:
类型解析器
SystemMetaObjectr:
SystemMetaObject.forObject创建MetaObject
ExceptionXxx
:异常处理
ReflectorFactory
:唯一实现类DefaultReflectorFactory.findForClass方法可以创建Reflector对象,默认开启缓存
2.反射工具包中有哪些类是核心类、有哪些核心方法?
Reflector:类的元数据,他是将一个类(一般为普通实体类)以反射的视角将它拆解开来待用,主要有以下几个属性
// 用来初始化数组,优化内存
private static final String[] EMPTY_STRING_ARRAY = new String[0];
// 类的class对象
private Class<?> type;
// 所有get方法的属性集合 getMethods的key集合
private String[] readablePropertyNames = EMPTY_STRING_ARRAY;
// 所有set方法的属性集合 setMethods的key集合
private String[] writeablePropertyNames = EMPTY_STRING_ARRAY;
// set方法集合 name -> setName方法的MethodInvoker对象
private Map<String, Invoker> setMethods = new HashMap<String, Invoker>();
// get方法集合 name -> getName方法的MethodInvoker对象
private Map<String, Invoker> getMethods = new HashMap<String, Invoker>();
// set入参值类型 name -> String.class
private Map<String, Class<?>> setTypes = new HashMap<String, Class<?>>();
// get返回值类型 name -> String.class
private Map<String, Class<?>> getTypes = new HashMap<String, Class<?>>();
// 空参构造方法
private Constructor<?> defaultConstructor;
// 忽略大小写的map集合 NAME -> name
private Map<String, String> caseInsensitivePropertyMap = new HashMap<String, String>();
所以Reflector对象的方法,大多也都是获取各种属性的方法
Metaclass:类的元数据,在Reflector的基础之上加了一层封装,在成员变量加上了ReflectorFactory,实现了Reflector的缓存,在部门方法上getSetterType等方法上添加了PropertyTokenizer工具类,实现了层级的对象属性查找
// 用来缓存reflector对象
private ReflectorFactory reflectorFactory;
// 类元数据装载实体
private Reflector reflector;
// 获取属性的get方法返回值类型
public Class<?> getGetterType(String name) {
PropertyTokenizer prop = new PropertyTokenizer(name);
if (prop.hasNext()) {
MetaClass metaProp = metaClassForProperty(prop);
return metaProp.getGetterType(prop.getChildren());
}
return getGetterType(prop);
}
ObjectWrapper:对象包装器 ,接口核心功能如下
Object get(PropertyTokenizer prop); // 获取值
void set(PropertyTokenizer prop, Object value); // 设置值
String findProperty(String name, boolean useCamelCaseMapping); 查找属性
String[] getGetterNames(); // 有get方法的属性集合
String[] getSetterNames(); // 有set方法的属性集合
Class<?> getSetterType(String name); // 获取set方法
Class<?> getGetterType(String name); // 获取get方法
boolean hasSetter(String name); // 是否有set方法
boolean hasGetter(String name); // 是否有get方法
MetaObject instantiatePropertyValue(String name, PropertyTokenizer prop, ObjectFactory objectFactory); // 构造MetaObject
boolean isCollection(); //isCollection add addAll 针对的是Collection类型下的对象
void add(Object element); // 添加
<E> void addAll(List<E> element); // 添加所有
MetaObject:对象元数据,核心属性为originalObject原始对象和objectWrapper,其他的都是工厂类 ,核心方法是objectWrapper的方法,通过操纵objectWrapper的方法来实现自己的方法
// 原始对象
private Object originalObject;
// 对象包装器
private ObjectWrapper objectWrapper;
// 对象工厂 单例
private ObjectFactory objectFactory;
// 对象包装器工厂 单例
private ObjectWrapperFactory objectWrapperFactory;
// 类元数据工厂 单例 + 缓存
private ReflectorFactory reflectorFactory;
3.该包下有哪些惊叹的设计或者代码?
待补充…
4.说说MetaClass和MetaObject有什么关系?
metaclass和metaObject有什么关系,我弄了好久才弄懂。单从类名看很容易不清楚他们俩的关系,但是只要看看类里面的成员变量就知道了,他们俩没有直接的联系,但是,当MetaObject对象里的ObjectWrapper接口的实例是BaseWrapper(BeanWrapper或MapWrapper)的时候,会有成员变量MetaObject、在BeanWrapper中会有MetaClass变量。所以,MetaObject在对象不是Collection的情况下,是包含MetaClass对象的,也就是对象元数据在对象不是集合类型的时候是包含类元数据的。
5.说说MetaObject和ObjectWrapper的关系?
当MetaObject的成员变量ObjectWrapper的实例为BaseWrapper子类的情况下,他们俩是相互依存的关系,互相将该对象地址指向对方。否则,没有半毛钱关系。
6.一个实体类在反射包中的赋值流程、详细到类和方法?
以MetaObject object = SystemMetaObject.forObject(new User())
为例来讲解步骤
1.进入SystemMetaObject.forObject静态方法,该类有很多默认成员变量,大多都是static new 出来的
2.进入MetaObject.forObject方法,此方法内部采用 new MetaObject(User对象,各种工厂实例) 的方式调用构造函数
3.进入构造函数给成员变量直接赋值,唯有Objectwrapper需要构造,最后一步是通过new XxxWrapper()方式给它赋值
4.因为User属于普通的Bean对象,程序会进入new BeanWrapper(this, object)初始化并赋值,此时的this代表本类对象
5.BeanWrapper初始化时成员变量有三个分别是object,metaObject,metaClass,其中前两个根据入参直接赋值,MetaClass通过MetaClass.forClass(Object,ReflectorFactory)构造MetaClass
6.MetaClass内部有Object和Reflector对象,其中Reflector对象需要实例化,内部是通过reflectorFactory.findForClass(Object)方式,最终是new Reflector(class)实例化Reflector对象
7.通过反射的方式获取set/get方法集合,set/get属性,set入参类型、get返回值类型元数据,初始化Reflector对象并返回,链式返回则初始化了整个MetaObject对象