目录
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 文件的配置信息: