Mybatis原理解析(一)解析全局xml配置文件生成SqlSessionFactory过程

在单单使用的Mybatis中我们都是如上图所写的步骤去实现的,那么我们这里就通过源码去看看SqlSessionFactory是怎么创建的吧。

源码深入

进去之后先是调用了里面的一个builde的重载方法,把我们的全局配置文件的stream传进去,点进去

里面是创建了一个XMLConfigBuilder对象,通过名字我们可以知道该对象应该是主要对我们的全局配置文件解析的一个类,那么我们来看下它的parse方法

 里面主要逻辑是parseConfiguration方法,并且最后返回的是一个Configuration对象,可以知道这个Configuration对象其实存放着我们解析的全局配置文件的信息了。

 可以看到在parseConfiguration方法中是去解析传过来的configuration节点下面各个节点的内容,比如properties节点,plugins节点,envrionment节点等等,然后解析到内容存到我们的Configuration对象中去,这里我们重点来看看解析mappers节点。

 在这里主需要就是解析mappers节点下的内容了,此时我们可以看到一句configuration.addMappers(mapperPackage),我们深入看看这个方法里面做了什么

发现里面有多层的封装,我们入到下图的这个方法中:

然后一步步地执行,执行到Set<Class<? extends Class<?>>> mapperSet = resolverUtil.getClasses();

遍历这个包含所有接口类路径的set集合,深入里面的addMapper(mapperClass)

 

深入loadXmlResource方法,我们可以发现

然后发现下面又创建了一个XMLMapperBuilder可以推断下面的parse方法就是解析xml的了,接着执行到xmlParse.parse方法 

  深入这个方法

继续深入configurationElement(parser.evalNode("/mapper"))这个方法

 对于这些节点来说我们比较关心的是select,insert,update,delete这些节点,所以深入最后一句buildStatementFromContext方法

再深入这个方法的重载

 可以看到有一个XMLStatementBuilder,这个类的parseStatementNode方法可能是解析xml文件的一个重要方法,再深入

下面我们看看这个方法里面拿这些解析到的属性值做了什么,继续深入

那么现在我们可以知道接口xml文件是如何解析的以及解析出的结果存放在哪里了。答案就是一个接口xml文件里面的每一个select|update|insert|delete标签对应的就是一个MappedStatement对象 ,这个结论很重要,对后面的执行crud操作以及插件都很有帮助。

上面就是MapperRegistry的addMapper方法执行过程,在这里面有一个重要的过程就是为每一个增删改查标签封装成一个个的MappedStatement对象。

我们回到MapperRegistry类里面,在这个类中,有一个变量名为knownMappers的map集合,里面的key值是我们的接口type(比如com.zyh.mybatis.dao.DeptMapper),value是MapperProxyFactory,如下图:

我们这里再去看看MapperProxyFactory类:

那么这个MapperProxyFactory的作用是什么尼,我们这里暂时不要管,其实它是与我们动态创建接口类有关的,现在我们只知道他里面的值是怎么来的就好。 

回到我们解析mappers标签那里,在解析该标签里面做了很多事情,其中就包括了根据package的包路径去获取我们在该包路径下面的接口类,并把每个接口类作为key存入MapperRegistry的一个变量名为knownMappers的Map对象中,同时该Map的每一个key对应的value是一个MapperProxyFactory对象,该对象在初始化的时候把我们传入的接口类对象赋值给了mapperInterface对象。

最后全局配置文件解析完成,返回了我们的Configuration对象,并且把Configuration对象传入重载方法build中,返回了一个实现了SqlSessionFactroy接口的DefaultSqlSessionFactory对象。

最后说一句,在初始化SqlSessionFactory的整个过程中,包括了初始化Configuration对象,而初始化Configuration对象时,里面有两个重要的属性:MappedStatement和MapperRegistry。Configuration对象初始化完成后,每一个MappedStatement就对应每一个的增删改查标签,Configuration对象有一个Map<String,MappedStatement>属性,它存放的就是MappedStatement对象,注意,一个增删改查标签的MappedStatement会存放两次在这个Map中,一次是以该标签的namespace+id为key,一次是直接id为key。如:

猜你喜欢

转载自blog.csdn.net/weixin_37689658/article/details/99086353
今日推荐