Mybatis初始化配置
我们可以从SqlSessionTest单元测试的Setup开始
private static SqlSessionFactory sqlMapper;@BeforeClasspublic static void setup() throws Exception { createBlogDataSource(); final String resource = "org/apache/ibatis/builder/MapperConfig.xml"; final Reader reader = Resources.getResourceAsReader(resource); sqlMapper = new SqlSessionFactoryBuilder().build(reader);} MapperConfig.xml文件:<configuration> <properties resource="databases/blog/blog-derby.properties"/> <!-- 配置信息 --> <settings> <setting name="cacheEnabled" value="true"/> <setting name="lazyLoadingEnabled" value="false"/> <setting name="multipleResultSetsEnabled" value="true"/> <setting name="useColumnLabel" value="true"/> <setting name="useGeneratedKeys" value="false"/> <setting name="defaultExecutorType" value="SIMPLE"/> <setting name="defaultStatementTimeout" value="25"/> </settings> <!-- 类型别名配置 --> <typeAliases> <typeAlias alias="Author" type="domain.blog.Author"/> <typeAlias alias="Blog" type="domain.blog.Blog"/> <typeAlias alias="Comment" type="domain.blog.Comment"/> <typeAlias alias="Post" type="domain.blog.Post"/> <typeAlias alias="Section" type="domain.blog.Section"/> <typeAlias alias="Tag" type="domain.blog.Tag"/> </typeAliases> <!-- 类型处理器 --> <typeHandlers> <typeHandler javaType="String" jdbcType="VARCHAR" handler="org.apache.ibatis.builder.ExampleTypeHandler"/> </typeHandlers> <!-- 对象工场 --> <objectFactory type="org.apache.ibatis.builder.ExampleObjectFactory"> <property name="objectFactoryProperty" value="100"/> </objectFactory> <!-- 插件配置 --> <plugins> <plugin interceptor="org.apache.ibatis.builder.ExamplePlugin"> <property name="pluginProperty" value="100"/> </plugin> </plugins> <!-- 环境配置 --> <environments default="development"> <environment id="development"> <transactionManager type="JDBC"> <property name="" value=""/> </transactionManager> <dataSource type="UNPOOLED"> <property name="driver" value="${driver}"/> <property name="url" value="${url}"/> <property name="username" value="${username}"/> <property name="password" value="${password}"/> </dataSource> </environment> </environments> <!-- SQL Mapper --> <mappers> <mapper resource="org/apache/ibatis/builder/AuthorMapper.xml"/> <mapper resource="org/apache/ibatis/builder/BlogMapper.xml"/> <mapper resource="org/apache/ibatis/builder/CachedAuthorMapper.xml"/> <mapper resource="org/apache/ibatis/builder/PostMapper.xml"/> <mapper resource="org/apache/ibatis/builder/NestedBlogMapper.xml"/> </mappers></configuration> 初始化入口从SqlSessionFactoryBuilder.build()方法开始XMLConfigBuilder parser = new XMLConfigBuilder(reader, environment, properties);return build(parser.parse()); XMLConfigBuilder构造器对构建出了Configuration对象, 并作了一定的初始化动作public XMLConfigBuilder(InputStream inputStream, String environment, Properties props) { this(new XPathParser(inputStream, true, props, new XMLMapperEntityResolver()), environment, props);}private XMLConfigBuilder(XPathParser parser, String environment, Properties props) { // 创建Configuration对象 super(new Configuration()); // 基于ThreadLocal的错误上下文 ErrorContext.instance().resource("SQL Mapper Configuration"); this.configuration.setVariables(props); this.parsed = false; this.environment = environment; // 核心的XML解析器 this.parser = parser;} 在new Configuration()中已经作了部分初始化, 如类别名注册等public Configuration() { // 注册事务工厂别名 typeAliasRegistry.registerAlias("JDBC", JdbcTransactionFactory.class); typeAliasRegistry.registerAlias("MANAGED", ManagedTransactionFactory.class); // 注册数据源工厂别名 typeAliasRegistry.registerAlias("JNDI", JndiDataSourceFactory.class); typeAliasRegistry.registerAlias("POOLED", PooledDataSourceFactory.class); typeAliasRegistry.registerAlias("UNPOOLED", UnpooledDataSourceFactory.class); // 注册缓存策略别名 typeAliasRegistry.registerAlias("PERPETUAL", PerpetualCache.class); typeAliasRegistry.registerAlias("FIFO", FifoCache.class); typeAliasRegistry.registerAlias("LRU", LruCache.class); typeAliasRegistry.registerAlias("SOFT", SoftCache.class); typeAliasRegistry.registerAlias("WEAK", WeakCache.class); // 数据库厂商标识提供者 typeAliasRegistry.registerAlias("DB_VENDOR", VendorDatabaseIdProvider.class); // 语言解析驱动类 typeAliasRegistry.registerAlias("XML", XMLLanguageDriver.class); typeAliasRegistry.registerAlias("RAW", RawLanguageDriver.class); // 注册日志处理类 typeAliasRegistry.registerAlias("SLF4J", Slf4jImpl.class); typeAliasRegistry.registerAlias("COMMONS_LOGGING", JakartaCommonsLoggingImpl.class); typeAliasRegistry.registerAlias("LOG4J", Log4jImpl.class); typeAliasRegistry.registerAlias("LOG4J2", Log4j2Impl.class); typeAliasRegistry.registerAlias("JDK_LOGGING", Jdk14LoggingImpl.class); typeAliasRegistry.registerAlias("STDOUT_LOGGING", StdOutImpl.class); typeAliasRegistry.registerAlias("NO_LOGGING", NoLoggingImpl.class); // 注册动态代理工厂, 基于Cglib或者JAVASSIST typeAliasRegistry.registerAlias("CGLIB", CglibProxyFactory.class); typeAliasRegistry.registerAlias("JAVASSIST", JavassistProxyFactory.class); // 解析动态SQL时用到的语言驱动, 3.2之后插拔自己的语言驱动 languageRegistry.setDefaultDriverClass(XMLLanguageDriver.class); languageRegistry.register(RawLanguageDriver.class);} 接下来就是parser.parse()核心方法public Configuration parse() { if (parsed) { throw new BuilderException("Each XMLConfigBuilder can only be used once."); } parsed = true; parseConfiguration(parser.evalNode("/configuration")); return configuration;}private void parseConfiguration(XNode root) { try { // 属性 propertiesElement(root.evalNode("properties")); // 别名 typeAliasesElement(root.evalNode("typeAliases")); // 插件 pluginElement(root.evalNode("plugins")); // 对象工厂 objectFactoryElement(root.evalNode("objectFactory")); // 对象包装器工厂 objectWrapperFactoryElement(root.evalNode("objectWrapperFactory")); // 设置 settingsElement(root.evalNode("settings")); // 环境 environmentsElement(root.evalNode("environments")); // read it after objectFactory and objectWrapperFactory issue #631 // 数据库提供商 databaseIdProviderElement(root.evalNode("databaseIdProvider")); // 类型处理器 typeHandlerElement(root.evalNode("typeHandlers")); // SQL mapper mapperElement(root.evalNode("mappers")); } catch (Exception e) { throw new BuilderException("Error parsing SQL Mapper Configuration. Cause: " + e, e); }