@Test
public void test01() throws IOException {
SqlSessionFactory sqlSessionFactory = new SqlSessionFactoryBuilder().build(Resources.getResourceAsReader("mybatis-config.xml"));
SqlSession sqlSession = sqlSessionFactory.openSession();
DocMapper mapper = sqlSession.getMapper(DocMapper.class);
Doc doc = mapper.getDocById(2);
System.out.println(doc);
}
首先先创建SQLSessionFactoryBuilder()对象,调用build()方法构建sqlSessionFactory对象
这里调用build方法需要 resource(配置文件的路径地址),environment、properties 三个参数,后两个默认可以为空
这里我们查看源码
public SqlSessionFactory build(Reader reader, Properties properties) {
return this.build((Reader)reader, (String)null, properties);
}
public SqlSessionFactory build(Reader reader, String environment, Properties properties) {
SqlSessionFactory var5;
try {
//解析配置文件
XMLConfigBuilder parser = new XMLConfigBuilder(reader, environment, properties);
//通过解析结果 构建SqlSessionFactory对象 ,这里默认是使用的 DefaultSqlSessionFactory来构建 sqlSessionFactory对象
var5 = this.build(parser.parse());
} catch (Exception var14) {
throw ExceptionFactory.wrapException("Error building SqlSession.", var14);
} finally {
ErrorContext.instance().reset();
try {
reader.close();
} catch (IOException var13) {
}
}
return var5;
}
public SqlSessionFactory build(Configuration config) {
return new DefaultSqlSessionFactory(config);
}
//我们主要观看这个方法的内部实现
parser.parse()
//进入方法的内部
public Configuration parse() {
if (this.parsed) {
throw new BuilderException("Each XMLConfigBuilder can only be used once.");
} else {
this.parsed = true;
//找到主节点并进行解析
this.parseConfiguration(this.parser.evalNode("/configuration"));
return this.configuration;
}
}
//进入parseConfiguration()方法
private void parseConfiguration(XNode root) {
try {
this.propertiesElement(root.evalNode("properties"));
Properties settings = this.settingsAsProperties(root.evalNode("settings"));
this.loadCustomVfs(settings);
this.loadCustomLogImpl(settings);
this.typeAliasesElement(root.evalNode("typeAliases"));
this.pluginElement(root.evalNode("plugins"));
this.objectFactoryElement(root.evalNode("objectFactory"));
this.objectWrapperFactoryElement(root.evalNode("objectWrapperFactory"));
this.reflectorFactoryElement(root.evalNode("reflectorFactory"));
this.settingsElement(settings);
this.environmentsElement(root.evalNode("environments"));
this.databaseIdProviderElement(root.evalNode("databaseIdProvider"));
this.typeHandlerElement(root.evalNode("typeHandlers"));
this.mapperElement(root.evalNode("mappers"));
} catch (Exception var3) {
throw new BuilderException("Error parsing SQL Mapper Configuration. Cause: " + var3, var3);
}
}
private void mapperElement(XNode parent) throws Exception {
if (parent != null) {
Iterator var2 = parent.getChildren().iterator();
while(true) {
while(var2.hasNext()) {
XNode child = (XNode)var2.next();
String resource;
if ("package".equals(child.getName())) {
resource = child.getStringAttribute("name");
this.configuration.addMappers(resource);
} else {
resource = child.getStringAttribute("resource");
String url = child.getStringAttribute("url");
String mapperClass = child.getStringAttribute("class");
XMLMapperBuilder mapperParser;
InputStream inputStream;
if (resource != null && url == null && mapperClass == null) {
ErrorContext.instance().resource(resource);
inputStream = Resources.getResourceAsStream(resource);
mapperParser = new XMLMapperBuilder(inputStream, this.configuration, resource, this.configuration.getSqlFragments());
mapperParser.parse();
} else if (resource == null && url != null && mapperClass == null) {
ErrorContext.instance().resource(url);
inputStream = Resources.getUrlAsStream(url);
mapperParser = new XMLMapperBuilder(inputStream, this.configuration, url, this.configuration.getSqlFragments());
mapperParser.parse();
} else {
if (resource != null || url != null || mapperClass == null) {
throw new BuilderException("A mapper element may only specify a url, resource or class, but not more than one.");
}
Class mapperInterface = Resources.classForName(mapperClass);
this.configuration.addMapper(mapperInterface);
}
}
}
return;
}
}
}
public void parse() {
if (!this.configuration.isResourceLoaded(this.resource)) {
this.configurationElement(this.parser.evalNode("/mapper"));
this.configuration.addLoadedResource(this.resource);
this.bindMapperForNamespace();
}
this.parsePendingResultMaps();
this.parsePendingCacheRefs();
this.parsePendingStatements();
}
private void bindMapperForNamespace() {
String namespace = this.builderAssistant.getCurrentNamespace();
if (namespace != null) {
Class boundType = null;
try {
boundType = Resources.classForName(namespace);
} catch (ClassNotFoundException var4) {
}
if (boundType != null && !this.configuration.hasMapper(boundType)) {
this.configuration.addLoadedResource("namespace:" + namespace);
this.configuration.addMapper(boundType);
}
}
}
public static Class classForName(String className) throws ClassNotFoundException {
return classLoaderWrapper.classForName(className);
}
public Class classForName(String name) throws ClassNotFoundException {
return this.classForName(name, this.getClassLoaders((ClassLoader)null));
}
Class classForName(String name, ClassLoader[] classLoader) throws ClassNotFoundException {
ClassLoader[] var3 = classLoader;
int var4 = classLoader.length;
for(int var5 = 0; var5 < var4; ++var5) {
ClassLoader cl = var3[var5];
if (null != cl) {
try {
//重点看这里,通过类名创建字节码对象
Class c = Class.forName(name, true, cl);
if (null != c) {
return c;
}
} catch (ClassNotFoundException var8) {
}
}
}
public void addMapper(Class type) {
this.mapperRegistry.addMapper(type);
}
public void addMapper(Class type) {
if (type.isInterface()) {
if (this.hasMapper(type)) {
throw new BindingException("Type " + type + " is already known to the MapperRegistry.");
}
boolean loadCompleted = false;
try {
//将type也就是我们的命名空间对象mapper放在一个map集合中作为一个key
this.knownMappers.put(type, new MapperProxyFactory(type));
MapperAnnotationBuilder parser = new MapperAnnotationBuilder(this.config, type);
parser.parse();
loadCompleted = true;
} finally {
if (!loadCompleted) {
this.knownMappers.remove(type);
}
}
}
}
private final Map, MapperProxyFactory> knownMappers = new HashMap();
第一部分我们先说到这里