学习MyBatis源码的过程中,发现其代码设计中使用了大量的建造者模式。
SqlSessionFactoryBuilder
public class SqlSessionFactoryBuilder {
public SqlSessionFactory build(Reader reader) {
return build(reader, null, null);
}
public SqlSessionFactory build(Reader reader, String environment) {
return build(reader, environment, null);
}
public SqlSessionFactory build(Reader reader, Properties properties) {
return build(reader, null, properties);
}
public SqlSessionFactory build(Reader reader, String environment, Properties properties) {
try {
XMLConfigBuilder parser = new XMLConfigBuilder(reader, environment, properties);
return build(parser.parse());
} catch (Exception e) {
throw ExceptionFactory.wrapException("Error building SqlSession.", e);
} finally {
ErrorContext.instance().reset();
try {
reader.close();
} catch (IOException e) {
// Intentionally ignore. Prefer previous error.
}
}
}
public SqlSessionFactory build(InputStream inputStream) {
return build(inputStream, null, null);
}
public SqlSessionFactory build(InputStream inputStream, String environment) {
return build(inputStream, environment, null);
}
public SqlSessionFactory build(InputStream inputStream, Properties properties) {
return build(inputStream, null, properties);
}
public SqlSessionFactory build(InputStream inputStream, String environment, Properties properties) {
try {
// XMLConfigBuilder会将XML配置文件的信息转换为Document对象,
// 而XML配置定义文件DTD转换成XMLMapperEntityResolver对象,
// 然后将二者封装到XpathParser对象中,
// XpathParser的作用是提供根据Xpath表达式获取基本的DOM节点Node信息的操作
XMLConfigBuilder parser = new XMLConfigBuilder(inputStream, environment, properties);
// parser.parse() 返回Configuration
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.
}
}
}
public SqlSessionFactory build(Configuration config) {
// 默认是DefaultSqlSessionFactory
return new DefaultSqlSessionFactory(config);
}
}
从源代码可得SqlSessionFactoryBuilder提供了很多种build方法,用于获得SqlSessionFactory对象。SqlSessionFactoryBuilder和SqlSessionFactory相互独立。
build方法传入的参数以Reader和InputStream可以分为两类
我们手动创建SqlSeesionFactory时一般是传入Reader或者是InputStream。具体的build()方法会根据参数不同进行选择。