简介:MetaClass是Mybatis对类级别的元信息的封装和处理,通过与属性工具类的结合, 实现了对复杂表达式的解析,实现了获取指定描述信息的功能
public class MetaClass { ???private ReflectorFactory reflectorFactory; ???private Reflector reflector; ???/** ????* 构造函数私有 ????*/ ???private MetaClass(Class<?> type, ReflectorFactory reflectorFactory) { ???????this.reflectorFactory = reflectorFactory; ???????this.reflector = reflectorFactory.findForClass(type); ???} ???/** ????* 调用构造方法创建MetaClass ????*/ ???public static MetaClass forClass(Class<?> type, ReflectorFactory reflectorFactory) { ???????return new MetaClass(type, reflectorFactory); ???} ???/** ????* 通过属性名称, 获取属性的MetaClass(解决成员变量是类的情况) ????*/ ???public MetaClass metaClassForProperty(String name) { ???????Class<?> propType = reflector.getGetterType(name); ???????return MetaClass.forClass(propType, reflectorFactory); ???} ???public String findProperty(String name) { ???????StringBuilder prop = buildProperty(name, new StringBuilder()); ???????return prop.length() > 0 ? prop.toString() : null; ???} ???public String findProperty(String name, boolean useCamelCaseMapping) { ???????if (useCamelCaseMapping) { ???????????name = name.replace("_", ""); ???????} ???????return findProperty(name); ???} ???public String[] getGetterNames() { ???????return reflector.getGetablePropertyNames(); ???} ???public String[] getSetterNames() { ???????return reflector.getSetablePropertyNames(); ???} ???public Class<?> getSetterType(String name) { ???????PropertyTokenizer prop = new PropertyTokenizer(name); ???????if (prop.hasNext()) { ???????????MetaClass metaProp = metaClassForProperty(prop.getName()); ???????????return metaProp.getSetterType(prop.getChildren()); ???????} else { ???????????return reflector.getSetterType(prop.getName()); ???????} ???} ???public Class<?> getGetterType(String name) { ???????PropertyTokenizer prop = new PropertyTokenizer(name); ???????if (prop.hasNext()) { ???????????MetaClass metaProp = metaClassForProperty(prop); ???????????return metaProp.getGetterType(prop.getChildren()); ???????} ???????// issue #506. Resolve the type inside a Collection Object ???????return getGetterType(prop); ???} ???private MetaClass metaClassForProperty(PropertyTokenizer prop) { ???????Class<?> propType = getGetterType(prop); ???????return MetaClass.forClass(propType, reflectorFactory); ???} ???private Class<?> getGetterType(PropertyTokenizer prop) { ???????Class<?> type = reflector.getGetterType(prop.getName()); ???????if (prop.getIndex() != null && Collection.class.isAssignableFrom(type)) { ???????????Type returnType = getGenericGetterType(prop.getName()); ???????????if (returnType instanceof ParameterizedType) { ???????????????Type[] actualTypeArguments = ((ParameterizedType) returnType).getActualTypeArguments(); ???????????????if (actualTypeArguments != null && actualTypeArguments.length == 1) { ???????????????????returnType = actualTypeArguments[0]; ???????????????????if (returnType instanceof Class) { ???????????????????????type = (Class<?>) returnType; ???????????????????} else if (returnType instanceof ParameterizedType) { ???????????????????????type = (Class<?>) ((ParameterizedType) returnType).getRawType(); ???????????????????} ???????????????} ???????????} ???????} ???????return type; ???} ???private Type getGenericGetterType(String propertyName) { ???????try { ???????????Invoker invoker = reflector.getGetInvoker(propertyName); ???????????if (invoker instanceof MethodInvoker) { ???????????????Field _method = MethodInvoker.class.getDeclaredField("method"); ???????????????_method.setAccessible(true); ???????????????Method method = (Method) _method.get(invoker); ???????????????return TypeParameterResolver.resolveReturnType(method, reflector.getType()); ???????????} else if (invoker instanceof GetFieldInvoker) { ???????????????Field _field = GetFieldInvoker.class.getDeclaredField("field"); ???????????????_field.setAccessible(true); ???????????????Field field = (Field) _field.get(invoker); ???????????????return TypeParameterResolver.resolveFieldType(field, reflector.getType()); ???????????} ???????} catch (NoSuchFieldException e) { ???????} catch (IllegalAccessException e) { ???????} ???????return null; ???} ???public boolean hasSetter(String name) { ???????PropertyTokenizer prop = new PropertyTokenizer(name); ???????if (prop.hasNext()) { ???????????if (reflector.hasSetter(prop.getName())) { ???????????????MetaClass metaProp = metaClassForProperty(prop.getName()); ???????????????return metaProp.hasSetter(prop.getChildren()); ???????????} else { ???????????????return false; ???????????} ???????} else { ???????????return reflector.hasSetter(prop.getName()); ???????} ???} ???public boolean hasGetter(String name) { ???????PropertyTokenizer prop = new PropertyTokenizer(name); ???????if (prop.hasNext()) { ???????????if (reflector.hasGetter(prop.getName())) { ???????????????MetaClass metaProp = metaClassForProperty(prop); ???????????????return metaProp.hasGetter(prop.getChildren()); ???????????} else { ???????????????return false; ???????????} ???????} else { ???????????return reflector.hasGetter(prop.getName()); ???????} ???} ???public Invoker getGetInvoker(String name) { ???????return reflector.getGetInvoker(name); ???} ???public Invoker getSetInvoker(String name) { ???????return reflector.getSetInvoker(name); ???} ???/** ????* 解析属性表达式 会去寻找reflector中是否有对应的的属性 ????*/ ???private StringBuilder buildProperty(String name, StringBuilder builder) { ???????// 解析属性表达式 ???????PropertyTokenizer prop = new PropertyTokenizer(name); ???????// 是否有子表达式 ???????if (prop.hasNext()) { ???????????// 查找对应的属性 ???????????String propertyName = reflector.findPropertyName(prop.getName()); ???????????if (propertyName != null) { ???????????????// 追加属性名 ???????????????builder.append(propertyName); ???????????????builder.append("."); ???????????????// 创建对应的 MetaClass 对象 ???????????????MetaClass metaProp = metaClassForProperty(propertyName); ???????????????// 解析子表达式, 递归 ???????????????metaProp.buildProperty(prop.getChildren(), builder); ???????????} ???????} else { ???????????// 根据名称查找属性 ???????????String propertyName = reflector.findPropertyName(name); ???????????if (propertyName != null) { ???????????????builder.append(propertyName); ???????????} ???????} ???????return builder; ???} ???public boolean hasDefaultConstructor() { ???????return reflector.hasDefaultConstructor(); ???}}
理解了这个方法(递归, 该类中有很多类似的), 就可以很好的对这个类进行理解, 以查找(richType.richProperty)为例:
- 通过 PropertyTokenizer 对表达式进行解析, 得到当前的 name = richType, children = richProperty
- 从 reflector 中查找该 richType 属性
- 将 richType 添加到 builder 中
- 使用 metaClassForProperty 创建 richType 的 MetaClass。
- 递归调用自身来处理子表达式
退出的条件就是没有子表达式。 这个就是为了, 我们类中有成员变量是类, 我们可以通过其找到他们的所有类及其属性。
注意, 在此过程中, ReflectorFactory 一直是同一个, 而其内部缓存了多个 Reflector 对象。
Mybatis框架基础支持层——反射工具箱之MetaClass(7)
原文地址:https://www.cnblogs.com/wly1-6/p/10333917.html