# 第07章 Configuration对象总结及其手动创建

# 7.1 创建Configuration对象的过程

第02章中结合源码分析,有较详细的描述MyBatis基本的初始化过程(省略掉部分细节):

1550243071111

  • 当SqlSessionFactoryBuilder执行build()方法,调用了XMLConfigBuilder的parse()方法,然后返回了Configuration对象。XMLConfigBuilder会将XML配置文件的信息转换为Document对象,而XML配置定义文件DTD转换成XMLMapperEntityResolver对象,然后将二者封装到XpathParser对象中,XpathParser的作用是提供根据Xpath表达式获取基本的DOM节点Node信息的操作。如下图所示:

1550329847925

1550329940848

  • 之后XMLConfigBuilder调用parse()方法:会从XPathParser中取出 <configuration>节点对应的Node对象,然后解析此Node节点的子Node:properties, settings, typeAliases,typeHandlers, objectFactory, objectWrapperFactory, plugins, environments,databaseIdProvider, mappers
public Configuration parse() {
     if (parsed) {
         throw new BuilderException("Each XMLConfigBuilder can only be used once.");
     }
     parsed = true;
     parseConfiguration(parser.evalNode("/configuration"));
     return configuration;
 }

/**
 * 解析 "/configuration"节点下的子节点信息,然后将解析的结果设置到Configuration对象中
 */
private void parseConfiguration(XNode root) {
    try {
        //1.首先处理properties 节点
        propertiesElement(root.evalNode("properties"));
        Properties settings = settingsAsProperties(root.evalNode("settings"));
        loadCustomVfs(settings);
        loadCustomLogImpl(settings);
        //2.处理typeAliases
        typeAliasesElement(root.evalNode("typeAliases"));
        //3.处理插件
        pluginElement(root.evalNode("plugins"));
        //4.处理objectFactory
        objectFactoryElement(root.evalNode("objectFactory"));
        //5.objectWrapperFactory
        objectWrapperFactoryElement(root.evalNode("objectWrapperFactory"));
        reflectorFactoryElement(root.evalNode("reflectorFactory"));
        //6.settings
        settingsElement(settings);
        //7.处理environments
        environmentsElement(root.evalNode("environments"));
        //8.databaseIdProvider
        databaseIdProviderElement(root.evalNode("databaseIdProvider"));
        //9.typeHandlers
        typeHandlerElement(root.evalNode("typeHandlers"));
        //10.mappers
        mapperElement(root.evalNode("mappers"));
    } catch (Exception e) {
        throw new BuilderException("Error parsing SQL Mapper Configuration. Cause: " + e, e);
    }
}
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
  • 然后将这些值解析出来设置到Configuration对象中

以environmentsElement(root.evalNode("environments")); 方法为例,讲解如何将environments的信息解析出来,设置到Configuration对象中的:

/*
   解析environments节点,并将结果设置到Configuration对象中
   注意:创建envronment时,如果SqlSessionFactoryBuilder指定了特定的环境(即数据源);
         则返回指定环境(数据源)的Environment对象,否则返回默认的Environment对象;
         这种方式实现了MyBatis可以连接多数据源
*/
private void environmentsElement(XNode context) throws Exception{
    if (context != null){
        if (environment == null){
            environment = context.getStringAttribute("default");
        }
        for (XNode child : context.getChildren()){
            String id = child.getStringAttribute("id");
            if (isSpecifiedEnvironment(id)){
                //1.创建事务工厂 TransactionFactory
                TransactionFactory txFactory = transactionManagerElement(child.evalNode("transactionManager"));
                DataSourceFactory dsFactory = dataSourceElement(child.evalNode("dataSource"));
                //2.创建数据源DataSource
                DataSource dataSource = dsFactory.getDataSource();
                //3. 构造Environment对象
                Environment.Builder environmentBuilder = new Environment.Builder(id)
                .transactionFactory(txFactory)
                .dataSource(dataSource);
                //4. 将创建的Envronment对象设置到configuration 对象中
                configuration.setEnvironment(environmentBuilder.build());
            }
        }
    }
}
private boolean isSpecifiedEnvironment(String id){
    if (environment == null){
        throw new BuilderException("No environment specified.");
    }
    else if (id == null){
        throw new BuilderException("Environment requires an id attribute.");
    }
    else if (environment.equals(id)){
        return true;
    }
    return false;
}
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
  • 返回Configuration对象

序列图:

1552221753986

# 7.2 手动加载XML配置文件

可以手动加载XML配置文件创建Configuration对象完成初始化,创建并使用SqlSessionFactory对象

String resource = "mybatis-config.xml";
InputStream inputStream = Resources.getResourceAsStream(resource);
//手动创建XMLConfigBuilder,并解析创建Configuration对象
XMLConfigBuilder parser = new XMLConfigBuilder(inputStream, null,null);
Configuration configuration=parser.parse();
//使用Configuration对象创建SqlSessionFactory
SqlSessionFactory sqlSessionFactory = new SqlSessionFactoryBuilder().build(configuration);
//使用MyBatis
SqlSession sqlSession = sqlSessionFactory.openSession();
List list = sqlSession.selectList("com.foo.bean.BlogMapper.queryAllBlogInfo");
1
2
3
4
5
6
7
8
9
10
Last Updated: 10/20/2019, 11:49:45 PM