聊聊mybatis的反射之Reflector类
【摘要】 聊聊mybatis的反射之Invoker模块 MethodInvoker GetFieldInvoker ReflectorFactory 总结 聊聊mybatis的反射之Invoker模块上篇文章中我们介绍了mybatis的Reflector的构造方法,深入源码分析了一波,并了解到对于属性的getter setter方法封装成map集合中,key是属性名,value是MethodInvo...
聊聊mybatis的反射之Invoker模块
上篇文章中我们介绍了mybatis的Reflector的构造方法,深入源码分析了一波,并了解到对于属性的getter setter方法封装成map集合中,key是属性名,value是MethodInvoker,没有getter setter方法的属性也是封装到了map中,key是属性名,value是GetFieldInvoker和SetFieldInvoker,他们都是Invoker接口的实现类,下面看一下Invoker接口:
public interface Invoker {
//调用
Object invoke(Object target, Object[] args) throws IllegalAccessException, InvocationTargetException;
//取得类型
Class<?> getType();
}
接口比较简单,只有两个方法:调用和获取类型,MethodInvoker, GetFieldInvoker ,SetFieldInvoker这三个类都实现了Invoker接口,MethodInvoker重写了invoke方法,方法中就是直接调用Method.invoke方法
MethodInvoker
public class MethodInvoker implements Invoker {
private Class<?> type;
private Method method;
public MethodInvoker(Method method) {
this.method = method;
if (method.getParameterTypes().length == 1) {
type = method.getParameterTypes()[0];
} else {
type = method.getReturnType();
}
}
//就是调用Method.invoke
@Override
public Object invoke(Object target, Object[] args) throws IllegalAccessException, InvocationTargetException {
return method.invoke(target, args);
}
@Override
public Class<?> getType() {
return type;
}
}
通过构造方法的逻辑,我们知道如果只有一个参数,返回参数类型,否则返回return的类型,在调用方法中直接调用了Method.invoke()方法
GetFieldInvoker
GetFieldInvoker是Field作为成员变量,invoke调用方法中直接调用field.get(target)方法,获取类型的时候也直接使用field.getType()方法来进行获取
public class GetFieldInvoker implements Invoker {
private Field field;
public GetFieldInvoker(Field field) {
this.field = field;
}
//就是调用Field.get
@Override
public Object invoke(Object target, Object[] args) throws IllegalAccessException, InvocationTargetException {
return field.get(target);
}
@Override
public Class<?> getType() {
return field.getType();
}
}
对于其他的Invoker的接口这里不再一一分析了,整体逻辑都是很简单的。
ReflectorFactory
另外,ReflectorFactory 是一个工厂接口,它的默认实现类是DefaultReflectorFactory
接口:
public interface ReflectorFactory {
boolean isClassCacheEnabled();
void setClassCacheEnabled(boolean classCacheEnabled);
Reflector findForClass(Class<?> type);
}
这里定义三个方法
而DefaultReflectorFactory实现类的代码如下:
public class DefaultReflectorFactory implements ReflectorFactory {
private boolean classCacheEnabled = true;
private final ConcurrentMap<Class<?>, Reflector> reflectorMap = new ConcurrentHashMap<>();
public DefaultReflectorFactory() {
}
@Override
public boolean isClassCacheEnabled() {
return classCacheEnabled;
}
@Override
public void setClassCacheEnabled(boolean classCacheEnabled) {
this.classCacheEnabled = classCacheEnabled;
}
/**
* 生产Reflector对象
* @param type 目标类型
* @return 目标类型的Reflector对象
*/
@Override
public Reflector findForClass(Class<?> type) {
if (classCacheEnabled) { // 允许缓存
// 生产入参type的反射器对象,并放入缓存
return reflectorMap.computeIfAbsent(type, Reflector::new);
} else {
return new Reflector(type);
}
}
}
DefaultReflectorFactory中有一个ConcurrentHashMap成员变量,使用ConcurrentHashMap来做缓存,缓存的是class对应的Reflector对象信息,在允许进行缓存的情况下,会将入参type和对应的反射器对象放入到缓存中
总结
这篇文章主要讲解了Invoker接口和它实现类GetFieldInvoker,以及ReflectorFactory接口和它的默认实现类,Invoker接口主要是用来更加Class类来生成MethodInvoker, GetFieldInvoker ,SetFieldInvoker具体对象信息的并保存在map中供其他方法使用,ReflectorFactory是主要是用于Reflector对象的缓存,它的默认实现类是DefaultReflectorFactory,缓存是利用的ConcurrentHashMap来进行缓存的,希望看完这篇文章让你对Mybatis的反射模块有所帮助
【声明】本内容来自华为云开发者社区博主,不代表华为云及华为云开发者社区的观点和立场。转载时必须标注文章的来源(华为云社区)、文章链接、文章作者等基本信息,否则作者和本社区有权追究责任。如果您发现本社区中有涉嫌抄袭的内容,欢迎发送邮件进行举报,并提供相关证据,一经查实,本社区将立刻删除涉嫌侵权内容,举报邮箱:
cloudbbs@huaweicloud.com
- 点赞
- 收藏
- 关注作者
作者其他文章
评论(0)