Mybatis可以用反射设置值吗? 我有一个类,它有一个属性,它的setter受到保护。所以我必须使用反射来设置这个值? Mybatis可以工作吗?
答案 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