MYBATIS反射模块
Invoker包
这个包中对Java的反射调用进行了二次封装,定义了一个Invoker接口和三个具体实现。我们首先来看Invoker接口
Invoker接口
这个接口定义了两个函数,invoke用来执行具体的调用,getType用来返回调用对象的具体的类型。
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 public interface Invoker { Object invoke (Object target, Object[] args) throws IllegalAccessException, InvocationTargetException; Class<?> getType(); }
GetFieldInvoker类
这两个类都实现了Invoker接口,都有一个类型为java.lang.reflect.Field的属性,这个属性在初始化时进行设置。
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 public class GetFieldInvoker implements Invoker { private final Field field; public GetFieldInvoker (Field field) { this .field = field; } @Override public Object invoke (Object target, Object[] args) throws IllegalAccessException { try { return field.get(target); } catch (IllegalAccessException e) { if (Reflector.canControlMemberAccessible()) { field.setAccessible(true ); return field.get(target); } else { throw e; } } } @Override public Class<?> getType() { return field.getType(); } }
SetFieldInvoker和GetFieldInvoker类
这两个类都实现了Invoker接口,都有一个类型为java.lang.reflect.Field的属性,这个属性在初始化时进行设置。
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 public SetFieldInvoker (Field field) { this .field = field; } public GetFieldInvoker (Field field) { this .field = field; }
getType函数返回的是Field的类型:
1 2 3 4 5 6 7 8 @Override public Class<?> getType() { return field.getType(); }
这两个类最大的不同在于对invoke函数的实现上,一个是调用fieldd的set方法,一个是调用Field的get方法。
获取字段的值 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 @Override public Object invoke (Object target, Object[] args) throws IllegalAccessException { try { return field.get(target); } catch (IllegalAccessException e) { if (Reflector.canControlMemberAccessible()) { field.setAccessible(true ); return field.get(target); } else { throw e; } } }
设置字段的值 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 @Override public Object invoke (Object target, Object[] args) throws IllegalAccessException { try { field.set(target, args[0 ]); } catch (IllegalAccessException e) { if (Reflector.canControlMemberAccessible()) { field.setAccessible(true ); field.set(target, args[0 ]); } else { throw e; } } return null ; }
MethodInvoker类
这个类相对前面两个类要复杂些,主要复杂的地方在于type的确定,这个type的确定是在构造函数中进行的
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 public class MethodInvoker implements Invoker { private final Class<?> type; private final Method method; public MethodInvoker (Method method) { this .method = method; if (method.getParameterTypes().length == 1 ) { type = method.getParameterTypes()[0 ]; } else { type = method.getReturnType(); } } @Override public Object invoke (Object target, Object[] args) throws IllegalAccessException, InvocationTargetException { try { return method.invoke(target, args); } catch (IllegalAccessException e) { if (Reflector.canControlMemberAccessible()) { method.setAccessible(true ); return method.invoke(target, args); } else { throw e; } } } @Override public Class<?> getType() { return type; } }
property包
property包主要来操作对象的属性的
PropertyCopier类
属性复制器,这个类就是就是将一个对象的属性值赋给另一个对象中对应的属性。
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 public final class PropertyCopier { private PropertyCopier () { } public static void copyBeanProperties (Class<?> type, Object sourceBean, Object destinationBean) { Class<?> parent = type; while (parent != null ) { final Field[] fields = parent.getDeclaredFields(); for (Field field : fields) { try { try { field.set(destinationBean, field.get(sourceBean)); } catch (IllegalAccessException e) { if (Reflector.canControlMemberAccessible()) { field.setAccessible(true ); field.set(destinationBean, field.get(sourceBean)); } else { throw e; } } } catch (Exception e) { } } parent = parent.getSuperclass(); } } }
PropertyNamer类
属性名工具类,主要用来处理getter和setter方法
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 public final class PropertyNamer { private PropertyNamer () { } public static String methodToProperty (String name) { if (name.startsWith("is" )) { name = name.substring(2 ); } else if (name.startsWith("get" ) || name.startsWith("set" )) { name = name.substring(3 ); } else { throw new ReflectionException ("Error parsing property name '" + name + "'. Didn't start with 'is', 'get' or 'set'." ); } if (name.length() == 1 || (name.length() > 1 && !Character.isUpperCase(name.charAt(1 )))) { name = name.substring(0 , 1 ).toLowerCase(Locale.ENGLISH) + name.substring(1 ); } return name; } public static boolean isProperty (String name) { return isGetter(name) || isSetter(name); } public static boolean isGetter (String name) { return (name.startsWith("get" ) && name.length() > 3 ) || (name.startsWith("is" ) && name.length() > 2 ); } public static boolean isSetter (String name) { return name.startsWith("set" ) && name.length() > 3 ; } }
PropertyTokenizer类
这个类是property包中的重量级类,该类会被reflection包中其他的类频繁的引用到。这个类实现了Iterable和Iterator这两个接口,但在使用时经常被用到的是Iterator接口中的hasNext这个函数
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 public class PropertyTokenizer implements Iterator <PropertyTokenizer> { private String name; private final String indexedName; private String index; private final String children; public PropertyTokenizer (String fullname) { int delim = fullname.indexOf('.' ); if (delim > -1 ) { name = fullname.substring(0 , delim); children = fullname.substring(delim + 1 ); } else { name = fullname; children = null ; } indexedName = name; delim = name.indexOf('[' ); if (delim > -1 ) { index = name.substring(delim + 1 , name.length() - 1 ); name = name.substring(0 , delim); } } public String getName () { return name; } public String getIndex () { return index; } public String getIndexedName () { return indexedName; } public String getChildren () { return children; } @Override public boolean hasNext () { return children != null ; } @Override public PropertyTokenizer next () { return new PropertyTokenizer (children); } @Override public void remove () { throw new UnsupportedOperationException ("Remove is not supported, as it has no meaning in the context of properties." ); } }