一.mybatis的初始化。
//mybaties持久化框架
public static void main(String[] args) {
try {
//读取配置文件
InputStream io=Resources.getResourceAsStream("mybatis-config.xml");
//根据数据流 构建session
SqlSessionFactory ssf=(new SqlSessionFactoryBuilder()).build(io);
SqlSession ss=ssf.openSession();
//根据接口 生成接口的实现类
UsersMapper um=ss.getMapper(UsersMapper.class);
} catch (IOException e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
}
1.加载配置文件。
通过Resources.getResourceAsStream("") 加载配置文件,并转换为InputStream对象;底层通过ClassLoader去加载资源。
/**
* 查找具有给定名称的资源
* java.lang.ClassLoader.getResource(String name)
.findResource(String name)
*
* 通过类加载器ClassLoader 去加载资源
*/
public URL getResource(String name) {
URL url;
if (parent != null) {
url = parent.getResource(name);
} else {
url = getBootstrapResource(name);
}
if (url == null) {
url = findResource(name);
}
return url;
}
2.解析配置文件。
SqlSessionFactory ssf=(new SqlSessionFactoryBuilder()).build(io);
public SqlSessionFactory build(InputStream inputStream, String environment, Properties properties) {
try {
XMLConfigBuilder parser = new XMLConfigBuilder(inputStream, environment, properties);
return build(parser.parse());
} catch (Exception e) {
throw ExceptionFactory.wrapException("Error building SqlSession.", e);
} finally {
ErrorContext.instance().reset();
try {
inputStream.close();
} catch (IOException e) {
// Intentionally ignore. Prefer previous error.
}
}
}
创建 XMLConfigBuilder对象,在mybatis中全局配置的解析是通过XMLConfigBuilder对象来解析的。具体解析在parse()方法中。
XMLConfigBuilder继承BaseBuilder
private XMLConfigBuilder(XPathParser parser, String environment, Properties props) {
//实例化过程中 会创建Configration对象 Configration对象是全局配置类
//然后调用父类构造方法
super(new Configuration());
ErrorContext.instance().resource("SQL Mapper Configuration");
this.configuration.setVariables(props);
this.parsed = false;
this.environment = environment;
this.parser = parser;
}
/**
*Configration对象的构造方法 会把类的别名和类的Class进行注册
*TypeAliasRegistry类中维护了一个map
*(这里先说一句) 配置文件中的别名都会在注册容器中去拿.class
* 如: 在配置中如果使用的JDBC的事务管理 在解析过程中就会从注册容器中拿到对应的
* 的JdbcTransactionFactory.class 然后去进行实例化 注入到Configration对象中
*/
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);
typeAliasRegistry.registerAlias("CGLIB", CglibProxyFactory.class);
typeAliasRegistry.registerAlias("JAVASSIST", JavassistProxyFactory.class);
languageRegistry.setDefaultDriverClass(XMLLanguageDriver.class);
languageRegistry.register(RawLanguageDriver.class);
}
调用super() 把新创建的Configration对象维护在BeseBuilder中
public BaseBuilder(Configuration configuration) {
this.configuration = configuration;
this.typeAliasRegistry = this.configuration.getTypeAliasRegistry();
this.typeHandlerRegistry = this.configuration.getTypeHandlerRegistry();
}
XMLConfigBuilder解析配置文件 调用parse().解析完标签,封装成对应的对象注入的configration对象中。
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 {
//issue #117 read properties first
propertiesElement(root.evalNode("properties"));
Properties settings = settingsAsProperties(root.evalNode("settings"));
loadCustomVfs(settings);
typeAliasesElement(root.evalNode("typeAliases"));
pluginElement(root.evalNode("plugins"));
objectFactoryElement(root.evalNode("objectFactory"));
objectWrapperFactoryElement(root.evalNode("objectWrapperFactory"));
reflectorFactoryElement(root.evalNode("reflectorFactory"));
settingsElement(settings);
// read it after objectFactory and objectWrapperFactory issue #631
environmentsElement(root.evalNode("environments"));
databaseIdProviderElement(root.evalNode("databaseIdProvider"));
typeHandlerElement(root.evalNode("typeHandlers"));
mapperElement(root.evalNode("mappers"));
} catch (Exception e) {
throw new BuilderException("Error parsing SQL Mapper Configuration. Cause: " + e, e);
}
}
XMLMapperBuilder解析Mapper.xml
XMLStatementBuilder解析mapper.xml中的select|insert|update|delete标签 MapperStatement对象。
mybatis的初始化,其实就是把配置文件解析成configuration对象的过程,所有的配置信息都维护在Configuration中。
写到这里不想写了。下次再详细补充吧。