1、Configuration對象主要數據結構:
1. protected Properties variables = new Properties();//全局屬性配置對象
2.protected final TypeAliasRegistry typeAliasRegistry = new TypeAliasRegistry();//別名對應容器
3.protected final InterceptorChain interceptorChain = new InterceptorChain();這個沒看懂是幹什麼的
4.protected ObjectFactory objectFactory = new DefaultObjectFactory();//對象建立工廠
5.protected ObjectWrapperFactory objectWrapperFactory = new DefaultObjectWrapperFactory();//對象包裝工廠
6.protected Environment environment;//存放當前環境信息的對象
7.protected String databaseId;//數據庫id,這點尚未搞清楚
8.protected final TypeHandlerRegistry typeHandlerRegistry = new TypeHandlerRegistry();//存放類型處理器的容器
9.protected final Set<String> loadedResources = new HashSet<String>();//存放mapper對象的容器java
2、構造準備工做
XMLConfigBuilder對象接收xml配置文件的inputStream,默認環境、屬性配置文件內容
XMLConfigBuilder創造了一個XPathParser對象,接收XMLConfigBuilder的inputStream,並緩存傳入屬性配置文件內容、xml配置文件描述dtd定義
XMLConfigBuilder創造了一個Configuration對象,並把屬性配置文件內容傳給這個Configuration對象
XMLConfigBuilder最終存儲的是Configuration對象(typeAliasRegistry、languageRegistry、Properties)、默認環境、xml對應的XPathParser解析對象
3、解析xml文件
XMLConfigBuilder對象進行具體的工做。
經過XPathParser對象的evalNode方法,從Configuration跟節點開始遍歷解析,獲得頂級Node,創造出一個XNode,並把屬性配置文件內容賦值給這個XNode(evalNode方法就是根據Node的名稱獲得XNode對象)
XMLConfigBuilder對象的parseConfiguration方法從頂級Node進行解析
1.對properties進行解析
a.Properties defaults = context.getChildrenAsProperties();先加載configuration文件中的property屬性
b.Resources.getResourceAsProperties(resource);加載properties文件中的屬性
c.Properties vars = configuration.getVariables();加載用戶java代碼的配置信息屬性信息
d.全部的屬性信息都保存到Configuration對象的(Properties variables)容器中(HashTable)
2.對typeAliases進行解析
a.在Configuration對象的默認構造方法中已經將Mybatis內置的別名信息加載到typeAliasRegistry容器中
b.XMLConfigBuilder對象的typeAliasRegistry.registerAlias(alias, clazz);將用戶自定義別名信息加載到typeAliasRegistry容器中(Map)
3.對plugins進行解析
a. configuration.addInterceptor(interceptorInstance);將配置的plugins加載的Configuration的InterceptorChain容器中(List)
4.對objectFactory進行解析
a.對象工廠,context.getChildrenAsProperties();獲得配置文件的name和value信息對
b. ObjectFactory factory = (ObjectFactory) resolveClass(type).newInstance();factory.setProperties(properties);建立對象工廠,並將屬性信息傳給他
c.把這個對象工廠加載到Configuration中的objectFactory對象,若是沒有配置,採用默認的DefaultObjectFactory
5.對objectWrapperFactory進行解析
a.ObjectWrapperFactory factory = (ObjectWrapperFactory) resolveClass(type).newInstance();建立對象包裝工程
b.configuration.setObjectWrapperFactory(factory);若是沒有配置採用默認的DefaultObjectWrapperFactory
6.對settings進行解析
a.爲Configuration對象的內置參數進行賦值操做,23個屬性值
7.對environments進行解析
a.若是用戶在初始化Configuration對象時沒有傳入環境信息對象,獲取xml文件中配置的默認環境id
b.根據默認配置的id,加載環境信息對象,主要是加載transactionManager和dataSource信息,這裏主要使用了TransactionFactory、DataSourceFactory、DataSource、 Environment.Builder 對象
TransactionFactory txFactory = transactionManagerElement(child.evalNode("transactionManager"));
DataSourceFactory dsFactory = dataSourceElement(child.evalNode("dataSource"));
DataSource dataSource = dsFactory.getDataSource();
Environment.Builder environmentBuilder = new Environment.Builder(id)
.transactionFactory(txFactory)
.dataSource(dataSource);
c.將環境變量賦值給Configuration對象configuration.setEnvironment(environmentBuilder.build());
8.對databaseIdProvider進行解析
a.若是有配置讀取配置, databaseIdProvider = (DatabaseIdProvider) resolveClass(type).newInstance(); databaseIdProvider.setProperties(properties);併爲其加載屬性信息
b.若是環境變量中已經有配置,須要優先考慮環境變量中的配置
Environment environment = configuration.getEnvironment();
if (environment != null && databaseIdProvider != null) {
String databaseId = databaseIdProvider.getDatabaseId(environment.getDataSource());
configuration.setDatabaseId(databaseId);
}
9.對typeHandlers進行解析
a.typeHandlerRegistry類已經默認加載了數據庫字段對應java基本類型的處理行爲
b.XMLConfigBuilder對象的typeHandlerRegistry.register(javaTypeClass, jdbcType, typeHandlerClass);將自定義類型處理器加載到Configuration對象的typeHandlerRegistry容器中(Map)
10.對mappers進行解析
a.根據mapper節點配置的mapper.xml文件路徑進行對象信息加載
b.將mapper.xml文件映射成對象,並保存到Configuration對象中
InputStream inputStream = Resources.getResourceAsStream(resource);
XMLMapperBuilder mapperParser = new XMLMapperBuilder(inputStream, configuration, resource, configuration.getSqlFragments());
mapperParser.parse();數據庫