源码分析-Mybatis源码阅读-懒加载机制

源码解析-Mybatis
01 源码分析-Mybatis源码阅读准备
02 源码分析-Mybatis源码阅读-会话层
03 源码分析-Mybatis源码阅读-执行器
04 源码分析-Mybatis源码阅读-Statement语句处理器
05 源码分析-Mybatis源码阅读-参数处理器
06 源码分析-Mybatis源码阅读-结果集处理器
07 源码分析-Mybatis源码阅读-主键生成器
08 源码分析-Mybatis源码阅读-懒加载机制
09 源码分析-Mybatis源码阅读-游标
10 源码分析-Mybatis源码阅读-类型处理器
11 源码分析-Mybatis源码阅读-缓存
12 源码分析-Mybatis源码阅读-Mapper代理

一 懒加载机制说明

懒加载机制相关代码在org.apache.ibatis.executor.loader包下,主要是针对嵌套结果进行懒加载,在03 源码分析-Mybatis源码阅读-执行器 文章中已经有介绍该包下所有类的相关说明。UML图如下:

image-20210603183533336

二 懒加载机制关键源码解读

ProxyFactory代理工厂接口类源码解读如下:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
/**
* 代理工厂接口
* @author Eduardo Macarron
*/
public interface ProxyFactory {

/**
* 设置工厂属性
* @param properties
*/
default void setProperties(Properties properties) {
// NOP
}

/**
* 创建一个代理
* @param target 代理的目标对象
* @param lazyLoader 要懒加载的属性Map
* @param configuration 配置
* @param objectFactory 对象工厂
* @param constructorArgTypes 构造方法参数类型列表
* @param constructorArgs 构造方法参数类型
* @return
*/
Object createProxy(Object target, ResultLoaderMap lazyLoader, Configuration configuration, ObjectFactory objectFactory, List<Class<?>> constructorArgTypes, List<Object> constructorArgs);

}

CglibProxyFactory代理工厂源码解读如下

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
/**
* Cglib代理工厂
* @author Clinton Begin
*/
public class CglibProxyFactory implements ProxyFactory {

private static final String FINALIZE_METHOD = "finalize";
private static final String WRITE_REPLACE_METHOD = "writeReplace";

public CglibProxyFactory() {
try {
Resources.classForName("net.sf.cglib.proxy.Enhancer");
} catch (Throwable e) {
throw new IllegalStateException("Cannot enable lazy loading because CGLIB is not available. Add CGLIB to your classpath.", e);
}
}

/**
* 创建一个代理
* @param target 代理的目标对象
* @param lazyLoader 要懒加载的属性Map
* @param configuration 配置
* @param objectFactory 对象工厂
* @param constructorArgTypes 构造方法参数类型列表
* @param constructorArgs 构造方法参数类型
* @return
*/
@Override
public Object createProxy(Object target, ResultLoaderMap lazyLoader, Configuration configuration, ObjectFactory objectFactory, List<Class<?>> constructorArgTypes, List<Object> constructorArgs) {
return EnhancedResultObjectProxyImpl.createProxy(target, lazyLoader, configuration, objectFactory, constructorArgTypes, constructorArgs);
}

/**
* 创建一个反序列化的代理
* @param target 代理的目标对象
* @param unloadedProperties 未加载的属性
* @param objectFactory 对象工厂
* @param constructorArgTypes 构造方法参数类型列表
* @param constructorArgs 构造方法参数类型
* @return
*/
public Object createDeserializationProxy(Object target, Map<String, ResultLoaderMap.LoadPair> unloadedProperties, ObjectFactory objectFactory, List<Class<?>> constructorArgTypes, List<Object> constructorArgs) {
return EnhancedDeserializationProxyImpl.createProxy(target, unloadedProperties, objectFactory, constructorArgTypes, constructorArgs);
}

/**
* 创建代理对象
* @param type 被代理对象类型
* @param callback 回调对象
* @param constructorArgTypes 构造方法参数类型列表
* @param constructorArgs 构造方法参数类型
* @return 代理对象
*/
static Object crateProxy(Class<?> type, Callback callback, List<Class<?>> constructorArgTypes, List<Object> constructorArgs) {
Enhancer enhancer = new Enhancer();
enhancer.setCallback(callback);
// 创建的代理对象 是 原对象的子类
enhancer.setSuperclass(type);
try {
// 获取类中的writeReplace方法
type.getDeclaredMethod(WRITE_REPLACE_METHOD);
// ObjectOutputStream will call writeReplace of objects returned by writeReplace
if (LogHolder.log.isDebugEnabled()) {
LogHolder.log.debug(WRITE_REPLACE_METHOD + " method was found on bean " + type + ", make sure it returns this");
}
} catch (NoSuchMethodException e) {
// 如果没找到writeReplace方法,则设置代理类继承WriteReplaceInterface接口,该接口中有writeReplace方法
enhancer.setInterfaces(new Class[] { WriteReplaceInterface.class });
} catch (SecurityException e) {
// nothing to do here
}
Object enhanced;
if (constructorArgTypes.isEmpty()) {
enhanced = enhancer.create();
} else {
Class<?>[] typesArray = constructorArgTypes.toArray(new Class[constructorArgTypes.size()]);
Object[] valuesArray = constructorArgs.toArray(new Object[constructorArgs.size()]);
enhanced = enhancer.create(typesArray, valuesArray);
}
return enhanced;
}

private static class EnhancedResultObjectProxyImpl implements MethodInterceptor {

/** 被代理类 */
private final Class<?> type;
/** 要懒加载的属性Map */
private final ResultLoaderMap lazyLoader;
/** 是否是激进懒加载 */
private final boolean aggressive;
/** 能够触发懒加载的方法名“equals”, “clone”, “hashCode”, “toString”。这四个方法名在Configuration中被初始化。 */
private final Set<String> lazyLoadTriggerMethods;
/** 对象工厂 */
private final ObjectFactory objectFactory;
/** 被代理类构造函数的参数类型列表 */
private final List<Class<?>> constructorArgTypes;
/** 被代理类构造函数的参数列表 */
private final List<Object> constructorArgs;

private EnhancedResultObjectProxyImpl(Class<?> type, ResultLoaderMap lazyLoader, Configuration configuration, ObjectFactory objectFactory, List<Class<?>> constructorArgTypes, List<Object> constructorArgs) {
this.type = type;
this.lazyLoader = lazyLoader;
this.aggressive = configuration.isAggressiveLazyLoading();
this.lazyLoadTriggerMethods = configuration.getLazyLoadTriggerMethods();
this.objectFactory = objectFactory;
this.constructorArgTypes = constructorArgTypes;
this.constructorArgs = constructorArgs;
}

public static Object createProxy(Object target, ResultLoaderMap lazyLoader, Configuration configuration, ObjectFactory objectFactory, List<Class<?>> constructorArgTypes, List<Object> constructorArgs) {
final Class<?> type = target.getClass();
EnhancedResultObjectProxyImpl callback = new EnhancedResultObjectProxyImpl(type, lazyLoader, configuration, objectFactory, constructorArgTypes, constructorArgs);
Object enhanced = crateProxy(type, callback, constructorArgTypes, constructorArgs);
PropertyCopier.copyBeanProperties(type, target, enhanced);
return enhanced;
}

/**
* 代理类的拦截方法
* @param enhanced 代理对象本身
* @param method 被调用的方法
* @param args 每调用的方法的参数
* @param methodProxy 用来调用父类的代理
* @return 方法返回值
* @throws Throwable
*/
@Override
public Object intercept(Object enhanced, Method method, Object[] args, MethodProxy methodProxy) throws Throwable {
// 取出被代理类中此次被调用的方法的名称
final String methodName = method.getName();
try {
// 防止属性的并发加载
synchronized (lazyLoader) {
// 被调用的是writeReplace方法
if (WRITE_REPLACE_METHOD.equals(methodName)) {
// 创建一个原始对象
Object original;
if (constructorArgTypes.isEmpty()) {
original = objectFactory.create(type);
} else {
original = objectFactory.create(type, constructorArgTypes, constructorArgs);
}
// 将被代理对象的属性拷贝进入新创建的对象
PropertyCopier.copyBeanProperties(type, enhanced, original);
// 存在懒加载属性
if (lazyLoader.size() > 0) {
// 则此时返回的信息要更多,不仅仅是原对象,还有相关的懒加载的设置等信息。因此使用CglibSerialStateHolder进行一次封装
return new CglibSerialStateHolder(original, lazyLoader.getProperties(), objectFactory, constructorArgTypes, constructorArgs);
} else {
// 没有未懒加载的属性了,那直接返回原对象进行序列化
return original;
}
} else {
// 存在懒加载属性且被调用的不是finalize方法
if (lazyLoader.size() > 0 && !FINALIZE_METHOD.equals(methodName)) {
// 设置了激进懒加载或者被调用的方法是能够触发全局懒加载的方法
if (aggressive || lazyLoadTriggerMethods.contains(methodName)) {
// 完成所有属性的懒加载
lazyLoader.loadAll();
} else if (PropertyNamer.isSetter(methodName)) { // 调用了属性写方法
// 则先清除该属性的懒加载设置。该属性不需要被懒加载了
final String property = PropertyNamer.methodToProperty(methodName);
lazyLoader.remove(property);
} else if (PropertyNamer.isGetter(methodName)) { // 调用了属性读方法
final String property = PropertyNamer.methodToProperty(methodName);
// 如果该属性是尚未加载的懒加载属性,则进行懒加载
if (lazyLoader.hasLoader(property)) {
lazyLoader.load(property);
}
}
}
}
}
// 触发被代理类的相应方法。能够进行到这里的是除去writeReplace方法外的方法,例如读写方法、toString方法等
return methodProxy.invokeSuper(enhanced, args);
} catch (Throwable t) {
throw ExceptionUtil.unwrapThrowable(t);
}
}
}

private static class EnhancedDeserializationProxyImpl extends AbstractEnhancedDeserializationProxy implements MethodInterceptor {

private EnhancedDeserializationProxyImpl(Class<?> type, Map<String, ResultLoaderMap.LoadPair> unloadedProperties, ObjectFactory objectFactory,
List<Class<?>> constructorArgTypes, List<Object> constructorArgs) {
super(type, unloadedProperties, objectFactory, constructorArgTypes, constructorArgs);
}

public static Object createProxy(Object target, Map<String, ResultLoaderMap.LoadPair> unloadedProperties, ObjectFactory objectFactory,
List<Class<?>> constructorArgTypes, List<Object> constructorArgs) {
final Class<?> type = target.getClass();
EnhancedDeserializationProxyImpl callback = new EnhancedDeserializationProxyImpl(type, unloadedProperties, objectFactory, constructorArgTypes, constructorArgs);
Object enhanced = crateProxy(type, callback, constructorArgTypes, constructorArgs);
PropertyCopier.copyBeanProperties(type, target, enhanced);
return enhanced;
}

@Override
public Object intercept(Object enhanced, Method method, Object[] args, MethodProxy methodProxy) throws Throwable {
final Object o = super.invoke(enhanced, method, args);
return o instanceof AbstractSerialStateHolder ? o : methodProxy.invokeSuper(o, args);
}

@Override
protected AbstractSerialStateHolder newSerialStateHolder(Object userBean, Map<String, ResultLoaderMap.LoadPair> unloadedProperties, ObjectFactory objectFactory,
List<Class<?>> constructorArgTypes, List<Object> constructorArgs) {
return new CglibSerialStateHolder(userBean, unloadedProperties, objectFactory, constructorArgTypes, constructorArgs);
}
}

private static class LogHolder {
private static final Log log = LogFactory.getLog(CglibProxyFactory.class);
}

}

JavassistProxyFactory代理工厂源码解读如下:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
/**
* Javassist代理工厂
* @author Eduardo Macarron
*/
public class JavassistProxyFactory implements org.apache.ibatis.executor.loader.ProxyFactory {

private static final String FINALIZE_METHOD = "finalize";
private static final String WRITE_REPLACE_METHOD = "writeReplace";

public JavassistProxyFactory() {
try {
Resources.classForName("javassist.util.proxy.ProxyFactory");
} catch (Throwable e) {
throw new IllegalStateException("Cannot enable lazy loading because Javassist is not available. Add Javassist to your classpath.", e);
}
}

/**
* 创建一个代理
* @param target 代理的目标对象
* @param lazyLoader 要懒加载的属性Map
* @param configuration 配置
* @param objectFactory 对象工厂
* @param constructorArgTypes 构造方法参数类型列表
* @param constructorArgs 构造方法参数类型
* @return
*/
@Override
public Object createProxy(Object target, ResultLoaderMap lazyLoader, Configuration configuration, ObjectFactory objectFactory, List<Class<?>> constructorArgTypes, List<Object> constructorArgs) {
return EnhancedResultObjectProxyImpl.createProxy(target, lazyLoader, configuration, objectFactory, constructorArgTypes, constructorArgs);
}

/**
* 创建一个反序列化的代理
* @param target 代理的目标对象
* @param unloadedProperties 未加载的属性
* @param objectFactory 对象工厂
* @param constructorArgTypes 构造方法参数类型列表
* @param constructorArgs 构造方法参数类型
* @return
*/
public Object createDeserializationProxy(Object target, Map<String, ResultLoaderMap.LoadPair> unloadedProperties, ObjectFactory objectFactory, List<Class<?>> constructorArgTypes, List<Object> constructorArgs) {
return EnhancedDeserializationProxyImpl.createProxy(target, unloadedProperties, objectFactory, constructorArgTypes, constructorArgs);
}

static Object crateProxy(Class<?> type, MethodHandler callback, List<Class<?>> constructorArgTypes, List<Object> constructorArgs) {

ProxyFactory enhancer = new ProxyFactory();
// 创建的代理对象 是 原对象的子类
enhancer.setSuperclass(type);

try {
// 获取类中的writeReplace方法
type.getDeclaredMethod(WRITE_REPLACE_METHOD);
// ObjectOutputStream will call writeReplace of objects returned by writeReplace
if (LogHolder.log.isDebugEnabled()) {
LogHolder.log.debug(WRITE_REPLACE_METHOD + " method was found on bean " + type + ", make sure it returns this");
}
} catch (NoSuchMethodException e) {
// 如果没找到writeReplace方法,则设置代理类继承WriteReplaceInterface接口,该接口中有writeReplace方法
enhancer.setInterfaces(new Class[] { WriteReplaceInterface.class });
} catch (SecurityException e) {
// nothing to do here
}

Object enhanced;
Class<?>[] typesArray = constructorArgTypes.toArray(new Class[constructorArgTypes.size()]);
Object[] valuesArray = constructorArgs.toArray(new Object[constructorArgs.size()]);
try {
enhanced = enhancer.create(typesArray, valuesArray);
} catch (Exception e) {
throw new ExecutorException("Error creating lazy proxy. Cause: " + e, e);
}
((Proxy) enhanced).setHandler(callback);
return enhanced;
}

private static class EnhancedResultObjectProxyImpl implements MethodHandler {
/** 被代理类 */
private final Class<?> type;
/** 要懒加载的属性Map */
private final ResultLoaderMap lazyLoader;
/** 是否是激进懒加载 */
private final boolean aggressive;
/** 能够触发懒加载的方法名“equals”, “clone”, “hashCode”, “toString”。这四个方法名在Configuration中被初始化。 */
private final Set<String> lazyLoadTriggerMethods;
/** 对象工厂 */
private final ObjectFactory objectFactory;
/** 被代理类构造函数的参数类型列表 */
private final List<Class<?>> constructorArgTypes;
/** 被代理类构造函数的参数列表 */
private final List<Object> constructorArgs;

private EnhancedResultObjectProxyImpl(Class<?> type, ResultLoaderMap lazyLoader, Configuration configuration, ObjectFactory objectFactory, List<Class<?>> constructorArgTypes, List<Object> constructorArgs) {
this.type = type;
this.lazyLoader = lazyLoader;
this.aggressive = configuration.isAggressiveLazyLoading();
this.lazyLoadTriggerMethods = configuration.getLazyLoadTriggerMethods();
this.objectFactory = objectFactory;
this.constructorArgTypes = constructorArgTypes;
this.constructorArgs = constructorArgs;
}

public static Object createProxy(Object target, ResultLoaderMap lazyLoader, Configuration configuration, ObjectFactory objectFactory, List<Class<?>> constructorArgTypes, List<Object> constructorArgs) {
final Class<?> type = target.getClass();
EnhancedResultObjectProxyImpl callback = new EnhancedResultObjectProxyImpl(type, lazyLoader, configuration, objectFactory, constructorArgTypes, constructorArgs);
Object enhanced = crateProxy(type, callback, constructorArgTypes, constructorArgs);
PropertyCopier.copyBeanProperties(type, target, enhanced);
return enhanced;
}

/**
* 代理类的拦截方法
* @param enhanced 代理对象本身
* @param method 被调用的方法
* @param args 每调用的方法的参数
* @param methodProxy 用来调用父类的代理
* @return 方法返回值
* @throws Throwable
*/
@Override
public Object invoke(Object enhanced, Method method, Method methodProxy, Object[] args) throws Throwable {
// 取出被代理类中此次被调用的方法的名称
final String methodName = method.getName();
try {
// 防止属性的并发加载
synchronized (lazyLoader) {
// 被调用的是writeReplace方法
if (WRITE_REPLACE_METHOD.equals(methodName)) {
Object original;
if (constructorArgTypes.isEmpty()) {
original = objectFactory.create(type);
} else {
original = objectFactory.create(type, constructorArgTypes, constructorArgs);
}
// 将被代理对象的属性拷贝进入新创建的对象
PropertyCopier.copyBeanProperties(type, enhanced, original);
if (lazyLoader.size() > 0) {
// 则此时返回的信息要更多,不仅仅是原对象,还有相关的懒加载的设置等信息。因此使用CglibSerialStateHolder进行一次封装
return new JavassistSerialStateHolder(original, lazyLoader.getProperties(), objectFactory, constructorArgTypes, constructorArgs);
} else {
// 没有未懒加载的属性了,那直接返回原对象进行序列化
return original;
}
} else {
// 存在懒加载属性且被调用的不是finalize方法
if (lazyLoader.size() > 0 && !FINALIZE_METHOD.equals(methodName)) {
// 如果是aggressive,则包括非懒加载属性的读操作也会触发懒加载
// 同时几个触发方法也会引发所有属性的加载
if (aggressive || lazyLoadTriggerMethods.contains(methodName)) {
lazyLoader.loadAll();
} else if (PropertyNamer.isSetter(methodName)) {
// 调用了赋值方法
// 得到要赋值的属性名称
final String property = PropertyNamer.methodToProperty(methodName);
// 因为被赋值,因此该属性的懒加载操作直接取消,以赋值为准
lazyLoader.remove(property);
} else if (PropertyNamer.isGetter(methodName)) {
// 获取读方法属性
final String property = PropertyNamer.methodToProperty(methodName);
// 判断对该属性是否有懒加载
if (lazyLoader.hasLoader(property)) {
// 如果有,就加载下
lazyLoader.load(property);
}
}
}
}
}
return methodProxy.invoke(enhanced, args);
} catch (Throwable t) {
throw ExceptionUtil.unwrapThrowable(t);
}
}
}

private static class EnhancedDeserializationProxyImpl extends AbstractEnhancedDeserializationProxy implements MethodHandler {

private EnhancedDeserializationProxyImpl(Class<?> type, Map<String, ResultLoaderMap.LoadPair> unloadedProperties, ObjectFactory objectFactory,
List<Class<?>> constructorArgTypes, List<Object> constructorArgs) {
super(type, unloadedProperties, objectFactory, constructorArgTypes, constructorArgs);
}

public static Object createProxy(Object target, Map<String, ResultLoaderMap.LoadPair> unloadedProperties, ObjectFactory objectFactory,
List<Class<?>> constructorArgTypes, List<Object> constructorArgs) {
final Class<?> type = target.getClass();
EnhancedDeserializationProxyImpl callback = new EnhancedDeserializationProxyImpl(type, unloadedProperties, objectFactory, constructorArgTypes, constructorArgs);
Object enhanced = crateProxy(type, callback, constructorArgTypes, constructorArgs);
PropertyCopier.copyBeanProperties(type, target, enhanced);
return enhanced;
}

@Override
public Object invoke(Object enhanced, Method method, Method methodProxy, Object[] args) throws Throwable {
final Object o = super.invoke(enhanced, method, args);
return o instanceof AbstractSerialStateHolder ? o : methodProxy.invoke(o, args);
}

@Override
protected AbstractSerialStateHolder newSerialStateHolder(Object userBean, Map<String, ResultLoaderMap.LoadPair> unloadedProperties, ObjectFactory objectFactory,
List<Class<?>> constructorArgTypes, List<Object> constructorArgs) {
return new JavassistSerialStateHolder(userBean, unloadedProperties, objectFactory, constructorArgTypes, constructorArgs);
}
}

private static class LogHolder {
private static final Log log = LogFactory.getLog(JavassistProxyFactory.class);
}

}

ResultLoader结果加载器源码解读:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
/**
* 结果加载器
* @author Clinton Begin
*/
public class ResultLoader {

protected final Configuration configuration;
/** 执行器 */
protected final Executor executor;
/** MappedStatement对象(包含完整的增删改查节点信息) */
protected final MappedStatement mappedStatement;
/** 参数对象 */
protected final Object parameterObject;
protected final Class<?> targetType;
/** 对象工厂,创建对象时使用 */
protected final ObjectFactory objectFactory;
protected final CacheKey cacheKey;
/** BoundSql对象(包含SQL语句、参数、实参信息) */
protected final BoundSql boundSql;
/** 结果提取器 */
protected final ResultExtractor resultExtractor;
/** 当前线程ID */
protected final long creatorThreadId;

/** 是否已加载 */
protected boolean loaded;
protected Object resultObject;

public ResultLoader(Configuration config, Executor executor, MappedStatement mappedStatement, Object parameterObject, Class<?> targetType, CacheKey cacheKey, BoundSql boundSql) {
this.configuration = config;
this.executor = executor;
this.mappedStatement = mappedStatement;
this.parameterObject = parameterObject;
this.targetType = targetType;
this.objectFactory = configuration.getObjectFactory();
this.cacheKey = cacheKey;
this.boundSql = boundSql;
this.resultExtractor = new ResultExtractor(configuration, objectFactory);
this.creatorThreadId = Thread.currentThread().getId();
}

public Object loadResult() throws SQLException {
// 查询结果列表
List<Object> list = selectList();
// 把结果列表转化为指定对象
resultObject = resultExtractor.extractObjectFromList(list, targetType);
return resultObject;
}

private <E> List<E> selectList() throws SQLException {
// 初始化ResultLoader时传入的执行器
Executor localExecutor = executor;
if (Thread.currentThread().getId() != this.creatorThreadId || localExecutor.isClosed()) {
// 执行器关闭,或者执行器属于其他线程,则创建新的执行器
localExecutor = newExecutor();
}
try {
// 查询结果
return localExecutor.query(mappedStatement, parameterObject, RowBounds.DEFAULT, Executor.NO_RESULT_HANDLER, cacheKey, boundSql);
} finally {
if (localExecutor != executor) {
localExecutor.close(false);
}
}
}

/**
* 这才是创建一个真的执行器,而ClosedExecutor是假的执行器
* @return
*/
private Executor newExecutor() {
final Environment environment = configuration.getEnvironment();
if (environment == null) {
throw new ExecutorException("ResultLoader could not load lazily. Environment was not configured.");
}
final DataSource ds = environment.getDataSource();
if (ds == null) {
throw new ExecutorException("ResultLoader could not load lazily. DataSource was not configured.");
}
final TransactionFactory transactionFactory = environment.getTransactionFactory();
final Transaction tx = transactionFactory.newTransaction(ds, null, false);
return configuration.newExecutor(tx, ExecutorType.SIMPLE);
}

public boolean wasNull() {
return resultObject == null;
}

}

ResultLoaderMap要懒加载的属性Map的源码解读:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
227
228
229
230
231
232
233
234
235
236
237
238
239
240
241
242
243
244
245
246
247
248
249
250
251
252
253
254
255
256
257
258
259
260
261
262
263
264
265
266
267
268
269
270
271
272
273
274
275
276
277
278
279
280
281
282
283
284
285
286
287
288
289
290
291
292
293
294
295
296
297
298
299
300
301
302
303
304
305
306
307
308
309
310
311
312
313
314
315
316
317
318
319
320
321
322
/**
* 要懒加载的属性Map
* @author Clinton Begin
* @author Franta Mejta
*/
public class ResultLoaderMap {

/**
* 一个对象持有
* 尚未完成惰性加载的属性map,key为属性名称的大写
*/
private final Map<String, LoadPair> loaderMap = new HashMap<>();

public void addLoader(String property, MetaObject metaResultObject, ResultLoader resultLoader) {
String upperFirst = getUppercaseFirstProperty(property);
if (!upperFirst.equalsIgnoreCase(property) && loaderMap.containsKey(upperFirst)) {
throw new ExecutorException("Nested lazy loaded result property '" + property
+ "' for query id '" + resultLoader.mappedStatement.getId()
+ " already exists in the result map. The leftmost property of all lazy loaded properties must be unique within a result map.");
}
loaderMap.put(upperFirst, new LoadPair(property, metaResultObject, resultLoader));
}

public final Map<String, LoadPair> getProperties() {
return new HashMap<>(this.loaderMap);
}

public Set<String> getPropertyNames() {
return loaderMap.keySet();
}

public int size() {
return loaderMap.size();
}

/**
* 判断指定属性上是否设置了惰性加载
* @param property 属性
* @return
*/
public boolean hasLoader(String property) {
return loaderMap.containsKey(property.toUpperCase(Locale.ENGLISH));
}

/**
* 把该对象的一个属性加载出来
* @param property 属性
* @return
* @throws SQLException
*/
public boolean load(String property) throws SQLException {
LoadPair pair = loaderMap.remove(property.toUpperCase(Locale.ENGLISH));
if (pair != null) {
pair.load();
return true;
}
return false;
}

public void remove(String property) {
loaderMap.remove(property.toUpperCase(Locale.ENGLISH));
}

/**
* 把该对象的所有属性加载出来
* @throws SQLException
*/
public void loadAll() throws SQLException {
// 读出该对象的所有属性集合
final Set<String> methodNameSet = loaderMap.keySet();
String[] methodNames = methodNameSet.toArray(new String[methodNameSet.size()]);
for (String methodName : methodNames) {
load(methodName);
}
}

private static String getUppercaseFirstProperty(String property) {
String[] parts = property.split("\\.");
return parts[0].toUpperCase(Locale.ENGLISH);
}

/**
* 还未加载的属性
* Property which was not loaded yet.
*/
public static class LoadPair implements Serializable {

private static final long serialVersionUID = 20130412;
/**
* 用来根据反射得到数据库连接的方法名
* Name of factory method which returns database connection.
*/
private static final String FACTORY_METHOD = "getConfiguration";
/**
* 判断是否经过了序列化的标志位,因为该属性被设置了transient,经过一次序列化和反序列化后会变为null
* Object to check whether we went through serialization..
*/
private final transient Object serializationCheck = new Object();
/**
* 输出结果对象的封装
* Meta object which sets loaded properties.
*/
private transient MetaObject metaResultObject;
/**
* 用以加载未加载属性的加载器
* Result loader which loads unread properties.
*/
private transient ResultLoader resultLoader;
/**
* 日志记录器
* Wow, logger.
*/
private transient Log log;
/**
* 用来获取数据库连接的工厂
* Factory class through which we get database connection.
*/
private Class<?> configurationFactory;
/**
* 未加载的属性的属性名
* Name of the unread property.
*/
private String property;
/**
* 能够加载未加载属性的SQL的编号
* ID of SQL statement which loads the property.
*/
private String mappedStatement;
/**
* 能够加载未加载属性的SQL的参数
* Parameter of the sql statement.
*/
private Serializable mappedParameter;

private LoadPair(final String property, MetaObject metaResultObject, ResultLoader resultLoader) {
this.property = property;
this.metaResultObject = metaResultObject;
this.resultLoader = resultLoader;

/* Save required information only if original object can be serialized. */
if (metaResultObject != null && metaResultObject.getOriginalObject() instanceof Serializable) {
final Object mappedStatementParameter = resultLoader.parameterObject;

/* @todo May the parameter be null? */
if (mappedStatementParameter instanceof Serializable) {
this.mappedStatement = resultLoader.mappedStatement.getId();
this.mappedParameter = (Serializable) mappedStatementParameter;

this.configurationFactory = resultLoader.configuration.getConfigurationFactory();
} else {
Log log = this.getLogger();
if (log.isDebugEnabled()) {
log.debug("Property [" + this.property + "] of ["
+ metaResultObject.getOriginalObject().getClass() + "] cannot be loaded "
+ "after deserialization. Make sure it's loaded before serializing "
+ "forenamed object.");
}
}
}
}

public void load() throws SQLException {
/* These field should not be null unless the loadpair was serialized.
* Yet in that case this method should not be called. */
if (this.metaResultObject == null) {
throw new IllegalArgumentException("metaResultObject is null");
}
if (this.resultLoader == null) {
throw new IllegalArgumentException("resultLoader is null");
}

this.load(null);
}

/**
* 进行加载操作
* @param userObject 需要被懒加载的对象(只有当this.metaResultObject == null || this.resultLoader == null才生效,否则会采用属性metaResultObject对应的对象)
* @throws SQLException
*/
public void load(final Object userObject) throws SQLException {
// 输出结果对象的封装不存在或者输出结果加载器不存在
if (this.metaResultObject == null || this.resultLoader == null) {
// 判断用以加载属性的对应的SQL语句存在
if (this.mappedParameter == null) {
throw new ExecutorException("Property [" + this.property + "] cannot be loaded because "
+ "required parameter of mapped statement ["
+ this.mappedStatement + "] is not serializable.");
}

final Configuration config = this.getConfiguration();
// 取出用来加载结果的SQL语句
final MappedStatement ms = config.getMappedStatement(this.mappedStatement);
if (ms == null) {
throw new ExecutorException("Cannot lazy load property [" + this.property
+ "] of deserialized object [" + userObject.getClass()
+ "] because configuration does not contain statement ["
+ this.mappedStatement + "]");
}

// 创建结果对象的包装
this.metaResultObject = config.newMetaObject(userObject);
// 创建结果加载器
this.resultLoader = new ResultLoader(config, new ClosedExecutor(), ms, this.mappedParameter,
metaResultObject.getSetterType(this.property), null, null);
}

/* 只要经历过持久化,则可能在别的线程中了。为这次惰性加载创建的新线程ResultLoader
* We are using a new executor because we may be (and likely are) on a new thread
* and executors aren't thread safe. (Is this sufficient?)
*
* A better approach would be making executors thread safe. */
if (this.serializationCheck == null) {
// 取出原来的ResultLoader中的必要信息,然后创建一个新的
// 这是因为load函数可能在不同的时间多次执行(第一次加载属性A,又过了好久加载属性B)。
// 而该对象的各种属性是跟随对象的,加载属性B时还保留着加载属性A时的状态,即ResultLoader是加载属性A时设置的
// 则此时ResultLoader中的Executor在ResultLoader中被替换成了一个能运行的Executor,而不是ClosedExecutor
// 能运行的Executor的状态可能不是close,这将导致它被复用,从而引发多线程问题
// 是不是被两次执行的一个关键点就是有没有经过序列化,因为执行完后会被序列化并持久化
final ResultLoader old = this.resultLoader;
this.resultLoader = new ResultLoader(old.configuration, new ClosedExecutor(), old.mappedStatement,
old.parameterObject, old.targetType, old.cacheKey, old.boundSql);
}

this.metaResultObject.setValue(property, this.resultLoader.loadResult());
}

private Configuration getConfiguration() {
if (this.configurationFactory == null) {
throw new ExecutorException("Cannot get Configuration as configuration factory was not set.");
}

Object configurationObject;
try {
final Method factoryMethod = this.configurationFactory.getDeclaredMethod(FACTORY_METHOD);
if (!Modifier.isStatic(factoryMethod.getModifiers())) {
throw new ExecutorException("Cannot get Configuration as factory method ["
+ this.configurationFactory + "]#["
+ FACTORY_METHOD + "] is not static.");
}

if (!factoryMethod.isAccessible()) {
configurationObject = AccessController.doPrivileged((PrivilegedExceptionAction<Object>) () -> {
try {
factoryMethod.setAccessible(true);
return factoryMethod.invoke(null);
} finally {
factoryMethod.setAccessible(false);
}
});
} else {
configurationObject = factoryMethod.invoke(null);
}
} catch (final ExecutorException ex) {
throw ex;
} catch (final NoSuchMethodException ex) {
throw new ExecutorException("Cannot get Configuration as factory class ["
+ this.configurationFactory + "] is missing factory method of name ["
+ FACTORY_METHOD + "].", ex);
} catch (final PrivilegedActionException ex) {
throw new ExecutorException("Cannot get Configuration as factory method ["
+ this.configurationFactory + "]#["
+ FACTORY_METHOD + "] threw an exception.", ex.getCause());
} catch (final Exception ex) {
throw new ExecutorException("Cannot get Configuration as factory method ["
+ this.configurationFactory + "]#["
+ FACTORY_METHOD + "] threw an exception.", ex);
}

if (!(configurationObject instanceof Configuration)) {
throw new ExecutorException("Cannot get Configuration as factory method ["
+ this.configurationFactory + "]#["
+ FACTORY_METHOD + "] didn't return [" + Configuration.class + "] but ["
+ (configurationObject == null ? "null" : configurationObject.getClass()) + "].");
}

return Configuration.class.cast(configurationObject);
}

private Log getLogger() {
if (this.log == null) {
this.log = LogFactory.getLog(this.getClass());
}
return this.log;
}
}

/**
* 该执行器唯一作用就是返回自己的状态:已经关闭了
* 这样,使用者看到关闭了的执行器就会重新创建新的执行器
*/
private static final class ClosedExecutor extends BaseExecutor {

public ClosedExecutor() {
super(null, null);
}

@Override
public boolean isClosed() {
return true;
}

@Override
protected int doUpdate(MappedStatement ms, Object parameter) throws SQLException {
throw new UnsupportedOperationException("Not supported.");
}

@Override
protected List<BatchResult> doFlushStatements(boolean isRollback) throws SQLException {
throw new UnsupportedOperationException("Not supported.");
}

@Override
protected <E> List<E> doQuery(MappedStatement ms, Object parameter, RowBounds rowBounds, ResultHandler resultHandler, BoundSql boundSql) throws SQLException {
throw new UnsupportedOperationException("Not supported.");
}

@Override
protected <E> Cursor<E> doQueryCursor(MappedStatement ms, Object parameter, RowBounds rowBounds, BoundSql boundSql) throws SQLException {
throw new UnsupportedOperationException("Not supported.");
}
}
}

AbstractSerialStateHolder抽象串行状态保持器源码解读:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
/**
* 抽象串行状态保持器
* 可以序列化,保存了原始对象、原始对象中未加载的属性Map、用来反射生成对象的相关信息
* @author Eduardo Macarron
* @author Franta Mejta
*/
public abstract class AbstractSerialStateHolder implements Externalizable {

private static final long serialVersionUID = 8940388717901644661L;
private static final ThreadLocal<ObjectOutputStream> stream = new ThreadLocal<>();
/** 序列化后的对象 */
private byte[] userBeanBytes = new byte[0];
/** 原对象 */
private Object userBean;
/** 未加载的属性 */
private Map<String, ResultLoaderMap.LoadPair> unloadedProperties;
/** 对象工厂,创建对象时使用 */
private ObjectFactory objectFactory;
/** 构造函数的属性类型列表,创建对象时使用 */
private Class<?>[] constructorArgTypes;
/** 构造函数的属性列表,创建对象时使用 */
private Object[] constructorArgs;

public AbstractSerialStateHolder() {
}

public AbstractSerialStateHolder(
final Object userBean,
final Map<String, ResultLoaderMap.LoadPair> unloadedProperties,
final ObjectFactory objectFactory,
List<Class<?>> constructorArgTypes,
List<Object> constructorArgs) {
this.userBean = userBean;
this.unloadedProperties = new HashMap<>(unloadedProperties);
this.objectFactory = objectFactory;
this.constructorArgTypes = constructorArgTypes.toArray(new Class<?>[0]);
this.constructorArgs = constructorArgs.toArray(new Object[0]);
}

/**
* 对对象进行序列化
* @param out 序列化结果将存入的流
* @throws IOException
*/
@Override
public final void writeExternal(final ObjectOutput out) throws IOException {
boolean firstRound = false;
final ByteArrayOutputStream baos = new ByteArrayOutputStream();
ObjectOutputStream os = stream.get();
if (os == null) {
os = new ObjectOutputStream(baos);
firstRound = true;
stream.set(os);
}

os.writeObject(this.userBean);
os.writeObject(this.unloadedProperties);
os.writeObject(this.objectFactory);
os.writeObject(this.constructorArgTypes);
os.writeObject(this.constructorArgs);

final byte[] bytes = baos.toByteArray();
out.writeObject(bytes);

if (firstRound) {
stream.remove();
}
}

/**
* 对对象进行反序列化
* @param in 反序列化输入的流
* @throws IOException
* @throws ClassNotFoundException
*/
@Override
public final void readExternal(final ObjectInput in) throws IOException, ClassNotFoundException {
final Object data = in.readObject();
if (data.getClass().isArray()) {
this.userBeanBytes = (byte[]) data;
} else {
this.userBean = data;
}
}

/**
* 反序列化时被调用,给出反序列化的对象
* @return 最终给出的反序列化对象
* @throws ObjectStreamException
*/
@SuppressWarnings("unchecked")
protected final Object readResolve() throws ObjectStreamException {
// 非第一次运行,直接输出已经解析好的被代理对象
/* Second run */
if (this.userBean != null && this.userBeanBytes.length == 0) {
return this.userBean;
}

SerialFilterChecker.check();

// 第一次运行时,反序列化输出
/* First run */
try (ObjectInputStream in = new ObjectInputStream(new ByteArrayInputStream(this.userBeanBytes))) {
this.userBean = in.readObject();
this.unloadedProperties = (Map<String, ResultLoaderMap.LoadPair>) in.readObject();
this.objectFactory = (ObjectFactory) in.readObject();
this.constructorArgTypes = (Class<?>[]) in.readObject();
this.constructorArgs = (Object[]) in.readObject();
} catch (final IOException ex) {
throw (ObjectStreamException) new StreamCorruptedException().initCause(ex);
} catch (final ClassNotFoundException ex) {
throw (ObjectStreamException) new InvalidClassException(ex.getLocalizedMessage()).initCause(ex);
}

final Map<String, ResultLoaderMap.LoadPair> arrayProps = new HashMap<>(this.unloadedProperties);
final List<Class<?>> arrayTypes = Arrays.asList(this.constructorArgTypes);
final List<Object> arrayValues = Arrays.asList(this.constructorArgs);

// 创建一个反序列化的代理输出,因此还是一个代理
return this.createDeserializationProxy(userBean, arrayProps, objectFactory, arrayTypes, arrayValues);
}

protected abstract Object createDeserializationProxy(Object target, Map<String, ResultLoaderMap.LoadPair> unloadedProperties, ObjectFactory objectFactory,
List<Class<?>> constructorArgTypes, List<Object> constructorArgs);
}