MyBatis源码之Binding模块

将用户自定义的Mapper接口与映射配置文件关联, 系统通过调用自定义Mapper接口中的方法执行相应的SQL语句, 提前校验拼写等错误

用户无需写Mapper的实现类, 由MyBatis动态代理生成

Snipaste_2024-12-19_11-19-47

1. MapperRegistry

Mapper注册表

1.1 构造方法

1
2
3
4
5
6
7
8
9
10
11
12
/**
* MyBatis Configuration 对象
*/
private final Configuration config;
/**
* MapperProxyFactory 映射
*/
private final Map<Class<?>, MapperProxyFactory<?>> knownMappers = new ConcurrentHashMap<>();

public MapperRegistry(Configuration config) {
this.config = config;
}

1.2 addMappers

1
2
3
4
5
6
7
8
9
10
11
12
13
14
public void addMappers(String packageName) {
addMappers(packageName, Object.class);
}

public void addMappers(String packageName, Class<?> superType) {
// 扫描指定包下的指定类, 参考IO模块
ResolverUtil<Class<?>> resolverUtil = new ResolverUtil<>();
resolverUtil.find(new ResolverUtil.IsA(superType), packageName);
Set<Class<? extends Class<?>>> mapperSet = resolverUtil.getClasses();
// 遍历添加到 knownMappers 中
for (Class<?> mapperClass : mapperSet) {
addMapper(mapperClass);
}
}

1.3 hasMapper

1
2
3
public <T> boolean hasMapper(Class<T> type) {
return knownMappers.containsKey(type);
}

1.4 addMapper

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
public <T> void addMapper(Class<T> type) {
// 接口
if (type.isInterface()) {
// 未添加过
if (hasMapper(type)) {
throw new BindingException("Type " + type + " is already known to the MapperRegistry.");
}
boolean loadCompleted = false;
try {
// 添加到 knownMappers 中
knownMappers.put(type, new MapperProxyFactory<>(type));
// It's important that the type is added before the parser is run
// otherwise the binding may automatically be attempted by the
// mapper parser. If the type is already known, it won't try.
// 解析 Mapper 的注解位置
MapperAnnotationBuilder parser = new MapperAnnotationBuilder(config, type);
parser.parse();
// 加载完成
loadCompleted = true;
} finally {
// 未加载完成 移除
if (!loadCompleted) {
knownMappers.remove(type);
}
}
}
}

1.5 getMapper

1
2
3
4
5
6
7
8
9
10
11
public <T> T getMapper(Class<T> type, SqlSession sqlSession) {
final MapperProxyFactory<T> mapperProxyFactory = (MapperProxyFactory<T>) knownMappers.get(type);
if (mapperProxyFactory == null) {
throw new BindingException("Type " + type + " is not known to the MapperRegistry.");
}
try {
return mapperProxyFactory.newInstance(sqlSession);
} catch (Exception e) {
throw new BindingException("Error getting mapper instance. Cause: " + e, e);
}
}

2. MapperProxyFactory

2.1 构造方法

1
2
3
4
5
6
7
8
9
10
11
12
13
14
private final Class<T> mapperInterface;
private final Map<Method, MapperMethodInvoker> methodCache = new ConcurrentHashMap<>();

public MapperProxyFactory(Class<T> mapperInterface) {
this.mapperInterface = mapperInterface;
}

public Class<T> getMapperInterface() {
return mapperInterface;
}

public Map<Method, MapperMethodInvoker> getMethodCache() {
return methodCache;
}

2.2 newInstance

jdk 动态代理

1
2
3
4
5
6
7
8
protected T newInstance(MapperProxy<T> mapperProxy) {
return (T) Proxy.newProxyInstance(mapperInterface.getClassLoader(), new Class[] { mapperInterface }, mapperProxy);
}

public T newInstance(SqlSession sqlSession) {
final MapperProxy<T> mapperProxy = new MapperProxy<>(sqlSession, mapperInterface, methodCache);
return newInstance(mapperProxy);
}

3. MapperProxy

3.1 构造方法

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
/**
* SqlSession 对象
*/
private final SqlSession sqlSession;
/**
* Mapper 接口
*/
private final Class<T> mapperInterface;
/**
* 方法与 MapperMethod 的映射
*/
private final Map<Method, MapperMethodInvoker> methodCache;

public MapperProxy(SqlSession sqlSession, Class<T> mapperInterface, Map<Method, MapperMethodInvoker> methodCache) {
this.sqlSession = sqlSession;
this.mapperInterface = mapperInterface;
this.methodCache = methodCache;
}

3.2 invoke

1
后续待完善