基于 Mybatis-3.5.0 版本
1.0 Invoker 执行器
org.apache.ibatis.reflection.invoker.Invoker 执行器接口, 这里主要是为了统一 getter 方法, setter 方法和 Field 个 get 和 set 执行时的差异, 使用了对象的适配器模式. 代码和类图如下:
- /**
- * 执行器接口: 为了统一 getter 方法, setter 方法和 Field 个 get 和 set 执行时的差异
- * 对象的适配器模式
- * @author Clinton Begin
- */
- public interface Invoker {
- /**
- * 执行调用
- * 主要用于执行: getter 方法, setter 方法和 Field 个 get 和 set
- * @param target 目标
- * @param args 参数
- * @return 结果
- * @throws IllegalAccessException
- * @throws InvocationTargetException
- */
- Object invoke(Object target, Object[] args) throws IllegalAccessException, InvocationTargetException;
- /**
- * @return 类
- * 差异:
- * 1.getter 方法 返回返回类型
- * 2.setter 方法 返回参数类型
- * 3.Field 返回自身的类型
- */
- Class<?> getType();
- }
代码都比较简单, 就直接上代码了
- 2.0 GetFieldInvoker
- /**
- * Field get 属性执行器
- * @author Clinton Begin
- */
- public class GetFieldInvoker implements Invoker {
- //Field 对象 即被适配者
- private final Field field;
- public GetFieldInvoker(Field field) {
- this.field = field;
- }
- /**
- * 获取 target Field 的属性值
- * 如果 Field 不可访问 (访问权限不够), 则设置 Accessible 强制访问
- */
- @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;
- }
- }
- }
- /**
- * 返回 Field 类型
- */
- @Override
- public Class<?> getType() {
- return field.getType();
- }
- }
- 2.1 SetFieldInvoker
- /**
- * Field set 属性执行器
- * @author Clinton Begin
- */
- public class SetFieldInvoker implements Invoker {
- // Field 对象 即被适配者
- private final Field field;
- public SetFieldInvoker(Field field) {
- this.field = field;
- }
- /**
- * 设置 target Field 的属性值
- * 如果 Field 不可访问 (访问权限不够), 则设置 Accessible 强制访问
- */
- @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;
- }
- /**
- * 返回 Field 类型
- */
- @Override
- public Class<?> getType() {
- return field.getType();
- }
- }
- 2.2 MethodInvoker
- /**
- * getter 或 setter 方法执行器
- * @author Clinton Begin
- */
- public class MethodInvoker implements Invoker {
- /**
- * getter 方法 返回返回类型
- * setter 方法 返回参数类型
- */
- private final Class<?> type;
- /**
- * Method 对象 即被适配者
- */
- private final Method method;
- public MethodInvoker(Method method) {
- this.method = method;
- if (method.getParameterTypes().length == 1) {
- type = method.getParameterTypes()[0];
- } else {
- type = method.getReturnType();
- }
- }
- /**
- * 执行 method 对象对应的方法
- * 如果 method 不可访问 (访问权限不够), 则设置 Accessible 强制访问
- */
- @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;
- }
- }
3.0 适配器模式
适配器模式下面这篇文章介绍的好不错:
《JAVA 与模式》之适配器模式
4.0 总结
大家在实际的开发中也可以巧用一些设计模式, 使得项目的代码更加健壮. 例如 Mybatis 反射模块中, 如果这里不使用适配器模式, 那在 Reflector 中缓存 setter 和 getter 的元信息时就不得不使用 4 个 Map 分别取缓存: getter 方法, setter 方法, Field-get 和 Field-set, 并且在实际的使用时还要去做 if 判断
失控的阿甘, 乐于分享, 记录点滴
来源: https://juejin.im/post/5c8f669b5188252d8f630450