MyBatis-3.4.2-源码分析17:XML解析之bindMapperForNamespace
MyBatis-3.4.2-源码分析17:XML解析之bindMapperForNamespace
强子哥哥 发表于8个月前
MyBatis-3.4.2-源码分析17:XML解析之bindMapperForNamespace
  • 发表于 8个月前
  • 阅读 6
  • 收藏 1
  • 点赞 0
  • 评论 0

腾讯云 技术升级10大核心产品年终让利>>>   

之前调试时,发现1个问题,就是mapperRegistry找不到对象

后来发现是mapper.xml的namespace里面的类名写得不对,然后来重新debug下

---

断点在

stop in org.apache.ibatis.builder.xml.XMLMapperBuilder.bindMapperForNamespace

调试

private void bindMapperForNamespace() {
		// 看到这里了
		String namespace = builderAssistant.getCurrentNamespace();
		System.out.println("namespace--->"+namespace);
		if (namespace != null) {
			// 如果设置了
			Class<?> boundType = null;
			try {
				// 看看是不是类
				boundType = Resources.classForName(namespace);
			} catch (ClassNotFoundException e) {
				// ignore, bound type is not required
			}
			//如果真的是类/接口
			if (boundType != null) {
				System.out.println("boundType--->"+boundType);
				//之前没有绑定
				if (!configuration.hasMapper(boundType)) {
					// Spring may not know the real resource name so we set a
					// flag
					// to prevent loading again this resource from the mapper
					// interface
					// look at MapperAnnotationBuilder#loadXmlResource
					//关键这里
					configuration.addLoadedResource("namespace:" + namespace);
					configuration.addMapper(boundType);
				}
			}
		}
	}

可以看到,关键就是

configuration.addLoadedResource("namespace:" + namespace);
					configuration.addMapper(boundType);

 跟进去

第1行就是标记这个资源加载过了,见下图

319    		loadedResources.add(resource);

main[1] print loadedResources
 loadedResources = "[mysql_mapper.xml]"
main[1] step
> 
Step completed: "thread=main", org.apache.ibatis.session.Configuration.addLoadedResource(), line=320 bci=11
320    	}

main[1] print loadedResources
 loadedResources = "[mysql_mapper.xml, namespace:interfaces.RoleMapper]"

看第2行

configuration.addMapper(boundType);
public <T> void addMapper(Class<T> type) {
		// 交给mapperRegistry负责
		mapperRegistry.addMapper(type);
	}

跟进去

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.put(type, new MapperProxyFactory<T>(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.
				MapperAnnotationBuilder parser = new MapperAnnotationBuilder(config, type);
				parser.parse();
				loadCompleted = true;
			} finally {
				if (!loadCompleted) {
					knownMappers.remove(type);
				}
			}
		}
	}

这里继续跟踪

knownMappers.put(type, new MapperProxyFactory<T>(type));

/**
 * @author Lasse Voss
 */
public class MapperProxyFactory<T> {
	// 接口类
	private final Class<T> mapperInterface;
	// 方法容器
	private final Map<Method, MapperMethod> methodCache = new ConcurrentHashMap<Method, MapperMethod>();

	public MapperProxyFactory(Class<T> mapperInterface) {
		// 设置接口类
		this.mapperInterface = mapperInterface;
		//end
	}

---然后就剩下

MapperAnnotationBuilder parser = new MapperAnnotationBuilder(config, type);
                parser.parse();

先看MapperAnnotationBuilder parser = new MapperAnnotationBuilder(config, type);

然后就是parse解析过程了
---

public void parse() {
		// 开始解析
		String resource = type.toString();
		// 如果没有加载过
		if (!configuration.isResourceLoaded(resource)) {
			// 进来
			// 这1行不执行
			loadXmlResource();
			// 标记已经加载过了
			configuration.addLoadedResource(resource);
			//
			assistant.setCurrentNamespace(type.getName());
			// 继续执行
			// 下面2行注释掉
			parseCache();
			parseCacheRef();
			//正式
			//获取类的方法
			Method[] methods = type.getMethods();
			//遍历每1个方法
			for (Method method : methods) {
				//
				try {
					// issue #237
					//如果不是bridge方法
					if (!method.isBridge()) {
						//解析此方法
						parseStatement(method);
					}
				} catch (IncompleteElementException e) {
					configuration.addIncompleteMethod(new MethodResolver(this, method));
				}
			}
		}
		parsePendingMethods();
	}

上面是注解解析的过程,暂且不表。

标签: MyBatis
共有 人打赏支持
强子哥哥
粉丝 836
博文 686
码字总数 713911
作品 8
×
强子哥哥
如果觉得我的文章对您有用,请随意打赏。您的支持将鼓励我继续创作!
* 金额(元)
¥1 ¥5 ¥10 ¥20 其他金额
打赏人
留言
* 支付类型
微信扫码支付
打赏金额:
已支付成功
打赏金额: