mybatis源码解读(二)——构建Configuration对象

目录

 


  Configuration 对象保存了所有mybatis的配置信息,主要包括:

  ①、 mybatis-configuration.xml 基础配置文件

  ②、 mapper.xml 映射器配置文件

回到顶部

1、读取配置文件

  前面例子有这么一段代码:

复制代码

1     private static SqlSessionFactory sqlSessionFactory;
2 
3     static{
4         InputStream inputStream = MybatisTest.class.getClassLoader().getResourceAsStream("mybatis-configuration.xml");
5         sqlSessionFactory = new SqlSessionFactoryBuilder().build(inputStream);
6     }

复制代码

  第 4 行代码是获取基础配置文件mybatis-configuration.xml 的字节流。接着我们将该字节流对象作为 bulid() 方法的参数传入进去。bulid 方法源码如下:这是一个多态方法

复制代码

 1     public SqlSessionFactory build(InputStream inputStream) {
 2         return build(inputStream, null, null);
 3     }
 4     public SqlSessionFactory build(InputStream inputStream, String environment, Properties properties) {
 5         try {
 6             XMLConfigBuilder parser = new XMLConfigBuilder(inputStream, environment, properties);
 7             return build(parser.parse());
 8         } catch (Exception e) {
 9             throw ExceptionFactory.wrapException("Error building SqlSession.", e);
10         } finally {
11             ErrorContext.instance().reset();
12             try {
13                 inputStream.close();
14             } catch (IOException e) {
15                 // Intentionally ignore. Prefer previous error.
16             }
17         }
18     }
19     public XMLConfigBuilder(InputStream inputStream, String environment, Properties props) {
20         this(new XPathParser(inputStream, true, props, new XMLMapperEntityResolver()), environment, props);
21     }
22     public XPathParser(InputStream inputStream, boolean validation, Properties variables, EntityResolver entityResolver) {
23         commonConstructor(validation, variables, entityResolver);
24         this.document = createDocument(new InputSource(inputStream));
25     }
26 
27     private Document createDocument(InputSource inputSource) {
28         // important: this must only be called AFTER common constructor
29         try {
30             DocumentBuilderFactory factory = DocumentBuilderFactory.newInstance();
31             factory.setValidating(validation);
32 
33             factory.setNamespaceAware(false);
34             factory.setIgnoringComments(true);
35             factory.setIgnoringElementContentWhitespace(false);
36             factory.setCoalescing(false);
37             factory.setExpandEntityReferences(true);
38 
39             DocumentBuilder builder = factory.newDocumentBuilder();
40             builder.setEntityResolver(entityResolver);
41             builder.setErrorHandler(new ErrorHandler() {
42                 @Override
43                 public void error(SAXParseException exception) throws SAXException {
44                     throw exception;
45                 }
46 
47                 @Override
48                 public void fatalError(SAXParseException exception) throws SAXException {
49                     throw exception;
50                 }
51 
52                 @Override
53                 public void warning(SAXParseException exception) throws SAXException {
54                 }
55             });
56             return builder.parse(inputSource);
57         } catch (Exception e) {
58             throw new BuilderException("Error creating document instance.  Cause: " + e, e);
59         }
60     }

复制代码

  这段代码我们不用深究,只需要知道这是将mybatis-configuration.xml文件解析成org.w3c.dom.Document对象,并将 Document 对象存储在 XPathParser 对象中便于后面解析。(XPath 语法解析xml具有很大的优势

  下一步就是将 Document 对象转换成 Configuration 对象:

  首先回到  SqlSessionFactory build(InputStream inputStream, String environment, Properties properties) 方法:

复制代码

 1   public SqlSessionFactory build(InputStream inputStream, String environment, Properties properties) {
 2     try {
 3       XMLConfigBuilder parser = new XMLConfigBuilder(inputStream, environment, properties);
 4       return build(parser.parse());
 5     } catch (Exception e) {
 6       throw ExceptionFactory.wrapException("Error building SqlSession.", e);
 7     } finally {
 8       ErrorContext.instance().reset();
 9       try {
10         inputStream.close();
11       } catch (IOException e) {
12         // Intentionally ignore. Prefer previous error.
13       }
14     }
15   }

复制代码

  第3行代码完成了xml文件到 Document 对象的转换,接下来我们看 build(parser.parse()) 方法:

复制代码

 1     public Configuration parse() {
 2         if (parsed) {
 3             throw new BuilderException("Each XMLConfigBuilder can only be used once.");
 4         }
 5         parsed = true;
 6         //从根节点 <configuration></configuration>处开始解析
 7         parseConfiguration(parser.evalNode("/configuration"));
 8         return configuration;
 9     }
10 
11     private void parseConfiguration(XNode root) {
12         try {
13             //分别解析相应的节点标签
14             propertiesElement(root.evalNode("properties"));
15             Properties settings = settingsAsProperties(root.evalNode("settings"));
16             loadCustomVfs(settings);
17             typeAliasesElement(root.evalNode("typeAliases"));
18             pluginElement(root.evalNode("plugins"));
19             objectFactoryElement(root.evalNode("objectFactory"));
20             objectWrapperFactoryElement(root.evalNode("objectWrapperFactory"));
21             reflectorFactoryElement(root.evalNode("reflectorFactory"));
22             settingsElement(settings);
23             environmentsElement(root.evalNode("environments"));
24             databaseIdProviderElement(root.evalNode("databaseIdProvider"));
25             typeHandlerElement(root.evalNode("typeHandlers"));
26             //解析引入的mapper.xml文件
27             mapperElement(root.evalNode("mappers"));
28         } catch (Exception e) {
29             throw new BuilderException("Error parsing SQL Mapper Configuration. Cause: " + e, e);
30         }
31     }

复制代码

  我们可以看看前一篇初始化环境博客中对于 mybatis-configuration.xml 文件的配置信息:

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值