Invoker介绍
Invoker是对getter和setter方法调用的封装,为了简化对属性和字段的操作,Invoker的实现类使用了适配器模式来屏蔽二者的差异,便于上层代码调用。
Invoker及其实现的类图
代码比较简单,直接看代码和注释即可
public interface Invoker {
//执行调用
Object invoke(Object target, Object[] args) throws IllegalAccessException, InvocationTargetException;
Class<?> getType();
}
MethodInvoker
public class MethodInvoker implements Invoker {
private final Class<?> type;
private final Method method;
public MethodInvoker(Method method) {
this.method = method;
//如果方法的形参列表长度为1,表示当前方法是set方法,故其type为形参的类型
if (method.getParameterTypes().length == 1) {
type = method.getParameterTypes()[0];
} else {
//形参列表不为1则为get方法,其type为方法返回类型
type = method.getReturnType();
}
}
@Override
public Object invoke(Object target, Object[] args) throws IllegalAccessException, InvocationTargetException {
try {
//执行调用,method.invoke(target, args)为被适配的点
return method.invoke(target, args);
} catch (IllegalAccessException e) {
//如果无法访问,则表示当前方法是private修饰的。
//于是mybaits会查看默认的安全管理器配置文件$JAVA_HOME/jre/lib/security/java.policy中
//suppressAccessChecks的值,用于判断是否可以使用setAccessible方法进行强制调用
if (Reflector.canControlMemberAccessible()) {
method.setAccessible(true);
return method.invoke(target, args);
} else {
throw e;
}
}
}
@Override
public Class<?> getType() {
return type;
}
}
关于java的安全管理器可以阅读该文章 https://www.cnblogs.com/yiwangzhibujian/p/6207212.html
AmbiguousMethodInvoker
具有二义性的方法调用器,当调用者调用invoke方法时会抛出ReflectionException
public class AmbiguousMethodInvoker extends MethodInvoker {
private final String exceptionMessage;
public AmbiguousMethodInvoker(Method method, String exceptionMessage) {
super(method);
this.exceptionMessage = exceptionMessage;
}
@Override
public Object invoke(Object target, Object[] args) throws IllegalAccessException, InvocationTargetException {
throw new ReflectionException(exceptionMessage);
}
}
GetFieldInvoker
获取字段值的调用器,用于适配对没有getter方法的字段值的获取
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
设置字段值的调用器,用于适配对没有setter方法的字段值的设置
public class SetFieldInvoker implements Invoker {
private final Field field;
public SetFieldInvoker(Field field) {
this.field = field;
}
@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;
}
@Override
public Class<?> getType() {
return field.getType();
}
}