Mybatis可以用反射设定价值吗?

时间:2016-03-15 04:15:13

标签: mybatis

Mybatis可以用反射设置值吗? 我有一个类,它有一个属性,它的setter受到保护。所以我必须使用反射来设置这个值? Mybatis可以工作吗?

1 个答案:

答案 0 :(得分:4)

是的,mybatis使用reflect来设置值。 在Reflator.java(mybatis 3.3.0)中,mybatis将配置set方法。

private void addSetMethods(Class<?> cls) {
    Map<String, List<Method>> conflictingSetters = new HashMap<String, List<Method>>();
    Method[] methods = getClassMethods(cls);
    for (Method method : methods) {
      String name = method.getName();
      if (name.startsWith("set") && name.length() > 3) {
        if (method.getParameterTypes().length == 1) {
          name = PropertyNamer.methodToProperty(name);
          addMethodConflict(conflictingSetters, name, method);
        }
      }
    }
    resolveSetterConflicts(conflictingSetters);
  }

如果你的类没有set方法,当addSetFields它将为该字段添加新的SetInvoker:

private void addSetField(Field field) {
    if (isValidPropertyName(field.getName())) {
      setMethods.put(field.getName(), new SetFieldInvoker(field));
      setTypes.put(field.getName(), field.getType());
    }
  }

和SetFieldInvoker是这样的:

/**
 * @author Clinton Begin
 */
public class SetFieldInvoker implements Invoker {
  private Field field;

  public SetFieldInvoker(Field field) {
    this.field = field;
  }

  @Override
  public Object invoke(Object target, Object[] args) throws IllegalAccessException, InvocationTargetException {
    field.set(target, args[0]);
    return null;
  }

  @Override
  public Class<?> getType() {
    return field.getType();
  }
}

DefaultResultSetHandler调用BeanWrapper的setBeanProperty方法将调用getSetInvoker

private void setBeanProperty(PropertyTokenizer prop, Object object, Object value) {
    try {
      Invoker method = metaClass.getSetInvoker(prop.getName());
      Object[] params = {value};
      try {
        method.invoke(object, params);
      } catch (Throwable t) {
        throw ExceptionUtil.unwrapThrowable(t);
      }
    } catch (Throwable t) {
      throw new ReflectionException("Could not set property '" + prop.getName() + "' of '" + object.getClass() + "' with value '" + value + "' Cause: " + t.toString(), t);
    }
  } 

整个调用链可能是这样的: DefaultSqlSession ## selectList - &gt; SimpleExecutor ## doQuery - &gt; SimpleStatementHandler ## query - &gt; DefaultResultSetHandler ## handleResultSets