映射文件解析完成后,并不意味着整个解析过程就结束了。此时还需要通过命名空间绑定 mapper 接口,这样才能将映射文件中的 SQL 语句和 mapper 接口中的方法绑定在一起,后续可直接通过调用 mapper 接口方法执行与之对应的 SQL 语句。
mapper 接口的绑定过程
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
| // -☆- XMLMapperBuilder private void bindMapperForNamespace() { // 获取映射文件的命名空间 String namespace = builderAssistant.getCurrentNamespace(); if (namespace != null) { Class<?> boundType = null; try { // 根据命名空间解析 mapper 类型 boundType = Resources.classForName(namespace); } catch (ClassNotFoundException e) {} if (boundType != null) { // 检测当前 mapper 类是否被绑定过 if (!configuration.hasMapper(boundType)) { configuration.addLoadedResource("namespace:" + namespace); // 绑定 mapper 类 configuration.addMapper(boundType); } } } }
// -☆- Configuration public <T> void addMapper(Class<T> type) { // 通过 MapperRegistry 绑定 mapper 类 mapperRegistry.addMapper(type); }
// -☆- MapperRegistry public <T> void addMapper(Class<T> type) { if (type.isInterface()) { if (hasMapper(type)) { throw new BindingException("……"); } boolean loadCompleted = false; try { // 将 type 和 MapperProxyFactory 进行绑定, // MapperProxyFactory 可为 mapper 接口生成代理类 knownMappers.put(type, new MapperProxyFactory<T>(type)); // 创建注解解析器。在 MyBatis 中,有 XML 和 注解两种配置方式可选 MapperAnnotationBuilder parser = new MapperAnnotationBuilder(config, type); // 解析注解中的信息 parser.parse(); loadCompleted = true; } finally { if (!loadCompleted) { knownMappers.remove(type); } } } }
|
- 获取命名空间,并根据命名空间解析 mapper 类型
- 将 type 和 MapperProxyFactory 实例存入 knownMappers 中
- 解析注解中的信息