反射是mybatis框架的基础,也是java开发框架的必用知识。在mybatis中提供了反射工具集来帮助mybatis完成参数转换、类型转换、参数填充、方法调用、动态代理等等功能。
一、Reflector类
- Reflector是mybatis反射模块的基础,每一个Reflector对象对应一个类,在Reflector中缓存了反射操作需要使用的类的元信息
定义的属性
public class Reflector { //是否缓存 private static boolean classCacheEnabled = true; //空数组 private static final String[] EMPTY_STRING_ARRAY = new String[0]; //用于存放类型--反射类对应的map private static final Map<Class<?>, Reflector> REFLECTOR_MAP = new ConcurrentHashMap<Class<?>, Reflector>(); //对象class类型 private Class<?> type; //存在相应的getter方法的属性 private String[] readablePropertyNames = EMPTY_STRING_ARRAY; //存在相应setter方法的属性 private String[] writeablePropertyNames = EMPTY_STRING_ARRAY; //记录属性相应的setter方法,key为属性名称,value为invoker对象 private Map<String, Invoker> setMethods = new HashMap<String, Invoker>(); //记录相应getter方法的集合 private Map<String, Invoker> getMethods = new HashMap<String, Invoker>(); //记录相应setter方法的参数值类型,value是setter方法的参数类型 private Map<String, Class<?>> setTypes = new HashMap<String, Class<?>>(); private Map<String, Class<?>> getTypes = new HashMap<String, Class<?>>(); //默认构造方法 private Constructor<?> defaultConstructor; //记录所有属性名称的集合 private Map<String, String> caseInsensitivePropertyMap = new HashMap<String, String>();
构造函数,对上述属性进行填充
//解析指定的class对象,并填充上面的集合 private Reflector(Class<?> clazz) { type = clazz; //查找clazz的默认构造方法 addDefaultConstructor(clazz); //处理getter方法并填充getMethods和getTypes集合 addGetMethods(clazz); //处理setter方法并填充setMethods和setTypes集合 addSetMethods(clazz); //处理没有getter和setter方法的字段 addFields(clazz); //根据getMethods、setMethods集合,初始化可读可写属性的集合 readablePropertyNames = getMethods.keySet().toArray(new String[getMethods.keySet().size()]); writeablePropertyNames = setMethods.keySet().toArray(new String[setMethods.keySet().size()]); //初始化caseInsensitivePropertyMap集合,记录所有大写格式的属性名称 for (String propName : readablePropertyNames) { caseInsensitivePropertyMap.put(propName.toUpperCase(Locale.ENGLISH), propName); } for (String propName : writeablePropertyNames) { caseInsensitivePropertyMap.put(propName.toUpperCase(Locale.ENGLISH), propName); } }
重点方法讲解
1.处理getter方法并填充getMethods和getTypes集合 private void addGetMethods(Class<?> cls) { Map<String, List<Method>> conflictingGetters = new HashMap<String, List<Method>>(); Method[] methods = getClassMethods(cls); //遍历并找出相应的get方法 for (Method method : methods) { String name = method.getName(); if (name.startsWith("get") && name.length() > 3) { if (method.getParameterTypes().length == 0) { name = PropertyNamer.methodToProperty(name); addMethodConflict(conflictingGetters, name, method); } } else if (name.startsWith("is") && name.length() > 2) { if (method.getParameterTypes().length == 0) { name = PropertyNamer.methodToProperty(name); addMethodConflict(conflictingGetters, name, method); } } } //解决子类和父类方法覆盖时候同时存在的冲突 resolveGetterConflicts(conflictingGetters); } 2.获取当前类及其父类中定义的所有方法的唯一签名及相应的Method对象 private Method[] getClassMethods(Class<?> cls) { HashMap<String, Method> uniqueMethods = new HashMap<String, Method>(); Class<?> currentClass = cls; while (currentClass != null) { //记录currentclass这个类中定义的全部方法 addUniqueMethods(uniqueMethods, currentClass.getDeclaredMethods()); //记录接口中定义的方法 Class<?>[] interfaces = currentClass.getInterfaces(); for (Class<?> anInterface : interfaces) { addUniqueMethods(uniqueMethods, anInterface.getMethods()); } //获取父类继续循环, currentClass = currentClass.getSuperclass(); } Collection<Method> methods = uniqueMethods.values(); //返回method数组 return methods.toArray(new Method[methods.size()]); } 3.为每一个方法生成唯一签名并记录到uniqueMethods集合中 private void addUniqueMethods(HashMap<String, Method> uniqueMethods, Method[] methods) { for (Method currentMethod : methods) { if (!currentMethod.isBridge()) { //返回值类型#方法名:参数类型列表(是唯一的可以作为唯一标识) String signature = getSignature(currentMethod); //是否已近添加 if (!uniqueMethods.containsKey(signature)) { if (canAccessPrivateMethods()) { try { currentMethod.setAccessible(true); } catch (Exception e) { // Ignored. This is only a final precaution, nothing we can do. } } uniqueMethods.put(signature, currentMethod); } } } } 4.获取方法签名(唯一标签) private String getSignature(Method method) { StringBuilder sb = new StringBuilder(); Class<?> returnType = method.getReturnType(); if (returnType != null) { sb.append(returnType.getName()).append('#'); } sb.append(method.getName()); Class<?>[] parameters = method.getParameterTypes(); for (int i = 0; i < parameters.length; i++) { if (i == 0) { sb.append(':'); } else { sb.append(','); } sb.append(parameters[i].getName()); } return sb.toString(); } 5.解决子类和父类方法覆盖时候同时存在的冲突 private void resolveGetterConflicts(Map<String, List<Method>> conflictingGetters) { for (String propName : conflictingGetters.keySet()) { List<Method> getters = conflictingGetters.get(propName); Iterator<Method> iterator = getters.iterator(); Method firstMethod = iterator.next(); if (getters.size() == 1) { //如果只有一个说明不存在冲突可以直接添加 addGetMethod(propName, firstMethod); } else { //不只有一个,需要比较getter方法的返回值,选择getter方法迭代过程中的临时变量,用于记录迭代到目前为止,最适合的getter方法发 Method getter = firstMethod; //记录返回值类型 Class<?> getterType = firstMethod.getReturnType(); while (iterator.hasNext()) { Method method = iterator.next(); Class<?> methodType = method.getReturnType();//获取返回值类型 if (methodType.equals(getterType)) {//前面应该过滤的 throw new ReflectionException("Illegal overloaded getter method with ambiguous type for property " + propName + " in class " + firstMethod.getDeclaringClass() + ". This breaks the JavaBeans " + "specification and can cause unpredicatble results."); //methodType是getterType的父类或者父接口或者两个相同 } else if (methodType.isAssignableFrom(getterType)) { // 当前最合适的方法的返回值就是当前方法返回值额子类 } else if (getterType.isAssignableFrom(methodType)) { getter = method; getterType = methodType; } else { throw new ReflectionException("Illegal overloaded getter method with ambiguous type for property " + propName + " in class " + firstMethod.getDeclaringClass() + ". This breaks the JavaBeans " + "specification and can cause unpredicatble results."); } } addGetMethod(propName, getter); } } } 6.完成方法的填充 private void addGetMethod(String name, Method method) { if (isValidPropertyName(name)) { //统一封装成invoker对象 getMethods.put(name, new MethodInvoker(method)); getTypes.put(name, method.getReturnType()); } } 7.验证属性是否合法 private boolean isValidPropertyName(String name) { return !(name.startsWith("$") || "serialVersionUID".equals(name) || "class".equals(name)); } ....其他方法类似
二、Invoker接口
- 完成Reflector初始化时候封装add*Method等方法在向上述集合添加元素的时候会将相应的getter/setter方法对应的method及字段对应的field对象统一封装成invoker对象
public interface Invoker {
//调用获取指定字段的值后,执行指定的方法
Object invoke(Object target, Object[] args) throws IllegalAccessException, InvocationTargetException;
Class<?> getType();
}
- Invoker接口有三个实现类,分别是MethodInvoker、GetFieldInvoker、SetFieldInvoker
三、ReflectorFactory接口
- 实现了对Reflector对象的创建和缓存
public interface ReflectorFactory { //检测该ReflectorFactory是否缓存了Reflector boolean isClassCacheEnabled(); //设置缓存 void setClassCacheEnabled(boolean classCacheEnabled); //创建指定class对应的reflector对象 Reflector findForClass(Class<?> type); }
- 实现类,DefaultReflectorFactory
public class DefaultReflectorFactory implements ReflectorFactory { //是否缓存 private boolean classCacheEnabled = true; //使用map按类型存Reflector private final ConcurrentMap<Class<?>, Reflector> reflectorMap = new ConcurrentHashMap<Class<?>, Reflector>(); public DefaultReflectorFactory() { } @Override public boolean isClassCacheEnabled() { return classCacheEnabled; } @Override public void setClassCacheEnabled(boolean classCacheEnabled) { this.classCacheEnabled = classCacheEnabled; } @Override public Reflector findForClass(Class<?> type) { if (classCacheEnabled) { // synchronized (type) removed see issue #461 Reflector cached = reflectorMap.get(type); if (cached == null) { cached = new Reflector(type); reflectorMap.put(type, cached); } return cached; } else { return new Reflector(type); } } }
四、TypeParameterResolver
- 是一个工具类,提供了一些列静态方法来解析指定类中的字段、方法返回值或者方法参数类型,TypeParameterResolver中各个静态方法之间的调用关系大致如图:
1.Type接口
jdk提供的顶级接口,表示的是所有类型的父接口
- Type接口的子类描述
(1)Class类(比较熟悉就不过多介绍) (2)ParameterizedType(参数化类型) public interface ParameterizedType extends Type { //返回参数化原始类型比如List<String> Type[] getActualTypeArguments(); //获取参数化类型的类型变量或者实际类型的列表 Type getRawType(); //返回类型所属的类型 Type getOwnerType(); } (3)TypeVariable(类型变量,反应在jvm编译该泛型前的信息) //例如List<T>中的T就是类型变量, 它在编译时候需要被转为一个具体的类型后才能使用 public interface TypeVariable<D extends GenericDeclaration> extends Type, AnnotatedElement { //获取类型变量的上边界,如果未明确声明上边界则默认Object,例如<K extends Person>那么上边界就是Person Type[] getBounds(); //获取声明该类型变量的原始类型,<K extends Person>原始类型就是K D getGenericDeclaration(); //获取源码中定义时候的名字 String getName(); //java8新增 AnnotatedType[] getAnnotatedBounds(); } (4)GenericArrayType //表示的是数组类型且组成元素是TypeVariable或者ParameterizedType public interface GenericArrayType extends Type { //返回数组的组成元素 Type getGenericComponentType(); } (5)WildcardType //表示统配符号泛型例如? extends Number public interface WildcardType extends Type { //返回泛型变量的上界 Type[] getUpperBounds(); //返回泛型变量的下界 Type[] getLowerBounds(); }
2、TypeParameterResolver工具类
- TypeParameterResolver通过resoveFieldType()方法、resolveReturnType()方法和resolveParamTypes()方法分别解析字段类型、方法返回值类型和方法参数列表中各个参数的类型。这三个方法的逻辑基本类似,这里以resolveFieldType为例子来进行介绍。
1.resoveFieldType方法 public static Type resolveFieldType(Field field, Type srcType) { Type fieldType = field.getGenericType();//获取字段的声明类型 Class<?> declaringClass = field.getDeclaringClass();//获取字段定义所在类的Class对象 return resolveType(fieldType, srcType, declaringClass); } 2.根据type类型(字段、方法参数、方法返回值)选择合适的方法进行解析,srcType表示查找该字段、返 回值或者方法参数的起始位置,declaringClass表示该字段、方法定义所在的类 private static Type resolveType(Type type, Type srcType, Class<?> declaringClass) { if (type instanceof TypeVariable) {//解析TypeVariable类型 return resolveTypeVar((TypeVariable<?>) type, srcType, declaringClass); } else if (type instanceof ParameterizedType) {//解析ParameterizedType类型 return resolveParameterizedType((ParameterizedType) type, srcType, declaringClass); } else if (type instanceof GenericArrayType) {//解析GenericArrayType类型 return resolveGenericArrayType((GenericArrayType) type, srcType, declaringClass); } else { return type;//class类型 } } 2.1resolveTypeVar负责解析TypeVariable,例如解析map字段的K和V private static Type resolveTypeVar(TypeVariable<?> typeVar, Type srcType, Class<?> declaringClass) { Type result = null; Class<?> clazz = null; if (srcType instanceof Class) { clazz = (Class<?>) srcType; } else if (srcType instanceof ParameterizedType) { ParameterizedType parameterizedType = (ParameterizedType) srcType; clazz = (Class<?>) parameterizedType.getRawType(); } else { throw new IllegalArgumentException("The 2nd arg must be Class or ParameterizedType, but was: " + srcType.getClass()); } if (clazz == declaringClass) { Type[] bounds = typeVar.getBounds();//获取上界 if(bounds.length > 0) { return bounds[0]; } return Object.class; } //获取父类 Type superclass = clazz.getGenericSuperclass(); //递归扫面父类进行解析 result = scanSuperTypes(typeVar, srcType, declaringClass, clazz, superclass); if (result != null) { return result; } Type[] superInterfaces = clazz.getGenericInterfaces(); for (Type superInterface : superInterfaces) { result = scanSuperTypes(typeVar, srcType, declaringClass, clazz, superInterface); if (result != null) { return result; } } //如果整个继承结构中没有解析成功,返回Object return Object.class; } 2.2解析参数化类型 private static ParameterizedType resolveParameterizedType(ParameterizedType parameterizedType, Type srcType, Class<?> declaringClass) { //获取原始类型对象的Class对象,例如public Map<K, V> map;对应的Class对象 Class<?> rawType = (Class<?>) parameterizedType.getRawType(); //类型变量K, V值 Type[] typeArgs = parameterizedType.getActualTypeArguments(); //用于保存解析后的结果 Type[] args = new Type[typeArgs.length]; for (int i = 0; i < typeArgs.length; i++) { if (typeArgs[i] instanceof TypeVariable) {//解析变量类型 args[i] = resolveTypeVar((TypeVariable<?>) typeArgs[i], srcType, declaringClass); } else if (typeArgs[i] instanceof ParameterizedType) { args[i] = resolveParameterizedType((ParameterizedType) typeArgs[i], srcType, declaringClass); } else if (typeArgs[i] instanceof WildcardType) { args[i] = resolveWildcardType((WildcardType) typeArgs[i], srcType, declaringClass); } else { args[i] = typeArgs[i]; } } //封装成ParameterizedType并返回,例子中的args为string return new ParameterizedTypeImpl(rawType, null, args); }
五、ObjectFactory接口
- 该接口提供了许多个create()方法的重载,通过这些create()方法可以创建指定类型的对象
public interface ObjectFactory { void setProperties(Properties properties);//设置配置信息 <T> T create(Class<T> type);//通过无参数构造器创建指定类的对象 //根据参数列表,从指定类型中选择合适的构造器创建对象 <T> T create(Class<T> type, List<Class<?>> constructorArgTypes, List<Object> constructorArgs); //判断是否是集合类 <T> boolean isCollection(Class<T> type); }
- 唯一实现类DefaultObjectFactory
是一个反射工厂,其中create方法通过instantiateClass方法实现,instantiateClass会根据传入的参数列表选择合适的构造函数实例化对象
public class DefaultObjectFactory implements ObjectFactory, Serializable { private static final long serialVersionUID = -8855120656740914948L; @Override public <T> T create(Class<T> type) { return create(type, null, null); } @SuppressWarnings("unchecked") @Override public <T> T create(Class<T> type, List<Class<?>> constructorArgTypes, List<Object> constructorArgs) { Class<?> classToCreate = resolveInterface(type); return (T) instantiateClass(classToCreate, constructorArgTypes, constructorArgs); } @Override public void setProperties(Properties properties) { // no props for default } private <T> T instantiateClass(Class<T> type, List<Class<?>> constructorArgTypes, List<Object> constructorArgs) { try { Constructor<T> constructor; //创建对象 if (constructorArgTypes == null || constructorArgs == null) { constructor = type.getDeclaredConstructor(); if (!constructor.isAccessible()) { constructor.setAccessible(true); } return constructor.newInstance(); } //根据指定的参数列表查找构造函数,并实例化对象 constructor = type.getDeclaredConstructor(constructorArgTypes.toArray(new Class[constructorArgTypes.size()])); if (!constructor.isAccessible()) { constructor.setAccessible(true); } return constructor.newInstance(constructorArgs.toArray(new Object[constructorArgs.size()])); } catch (Exception e) { StringBuilder argTypes = new StringBuilder(); if (constructorArgTypes != null && !constructorArgTypes.isEmpty()) { for (Class<?> argType : constructorArgTypes) { argTypes.append(argType.getSimpleName()); argTypes.append(","); } argTypes.deleteCharAt(argTypes.length() - 1); // remove trailing , } StringBuilder argValues = new StringBuilder(); if (constructorArgs != null && !constructorArgs.isEmpty()) { for (Object argValue : constructorArgs) { argValues.append(String.valueOf(argValue)); argValues.append(","); } argValues.deleteCharAt(argValues.length() - 1); // remove trailing , } throw new ReflectionException("Error instantiating " + type + " with invalid types (" + argTypes + ") or values (" + argValues + "). Cause: " + e, e); } } .... }
- 同时提供了在config文件中指定自定义的ObjectFactory接口实现类,扩展功能
六、MetaClass
- MetaClass通过Reflector和PropertyTokenizer组合使用,实现了对复杂的属性表达式的解析并实现了获取指定属性描述信息的功能
源码解读待定...
七、ObjectWrapper
- 对类级别的元信息的封装和处理,通过对对象的包装,抽象了对象的属性信息,定义了一系列查询对象属性信息的方法,以及更新属性的方法
源码解读待定...