一、什么是构建者模式
构建者模式是一种非常常见的构建型设计模式,很多常用的框架中都会见到这种设计模式,采用该设计模式时的类大多以Builder作为后缀。正常一个对象的创建是使用new关键字完成,但是如果创建对象
需要的构造参数很多,且不能保证每个参数都是正确的或者不能一次性得到构建所需的所有参数,就需要将构建逻辑从对象本身抽离出来,让对象只关注功能,把构建交给构建类,这样可以简化对象的构建,
也可以达到分步构建对象的目的,构建者模式大多用在解析文本参数创建对象的场景中,在框架配置场景中也很常见。一般情况下,都是通过一个中间参数类封装对象构建参数,一个构建类负责构建,
下面是构建者模式简单的一个例子:
/** * 中间参数类,一般情况,该类都是解析配置文本初始化,参数都有默认值 */ public class Config { private long num = 0; //编号 private String name = ""; //姓名 private long height = 0; //身高 public long getNum() { return num; } public void setNum(long num) { this.num = num; } public String getName() { return name; } public void setName(String name) { this.name = name; } public long getHeight() { return height; } public void setHeight(long height) { this.height = height; } }
/** * 构建目标类 */ public class Person { private long num; private String name; private long height; public Person(Config config) { this.num = config.getNum(); this.name = config.getName(); this.height = config.getHeight(); } public long getNum() { return num; } public void setNum(long num) { this.num = num; } public String getName() { return name; } public void setName(String name) { this.name = name; } public long getHeight() { return height; } public void setHeight(long height) { this.height = height; }
@Override
public String toString() {
return "Person{" +
"num=" + num +
", name='" + name + '\'' +
", height=" + height +
'}';
}
}
/** * 构建者类 */ public class PersonBuilder { private Config config; public PersonBuilder(Config config) { this.config = config; } public PersonBuilder setName(String name) { this.config.setName(name); return this; } public PersonBuilder setNum(long num) { this.config.setNum(num); return this; } public PersonBuilder setHeight(long height){ this.config.setHeight(height); return this; } public Person build() { return new Person(this.config); } }
public class Test { public static void main(String[] args) { Person person = new PersonBuilder(new Config()).setNum(10).setName("aFan").setHeight(178).build(); System.out.println(person); } }
运行结果:
二、SqlSessionFactoryBuilder类解析
上面认识了构建者模式,那么理解SqlSessionFactory的创建过程也就比较容易了,因为该类的创建也是通过构建者模式完成,mybatis框架中有着大量的配置参数,有些参数是初始化时需要的,如数据源配置,延迟加载配置,事务配置等,有些是框架运行过程中需要的,如sql映射等,所以mybatis使用构建者模式也就不足为奇。构建SqlSessionFactory分为了三步:
第一步,通过XMLConfigBuilder解析xml文件,生成xmlConfigBuilder对象
第二步,初始化xmlConfigBuilder对象,生成配置类Configuration
第三步,通过build方法,生成DefaultSqlSessionFactory对象
public SqlSessionFactory build(InputStream inputStream, String environment, Properties properties) { try { /*解析xml文件,封装成一个XMLConfigBuilder对象*/ XMLConfigBuilder parser = new XMLConfigBuilder(inputStream, environment, properties); /*生成一个参数类Configuration对象,然后通过该参数类创建DefaultSqlSessionFactory对象*/ Configuration config = parser.parse(); return build(config); } 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) { return new DefaultSqlSessionFactory(config); } }
上述三步都是在SqlSessionFactoryBuilder类中进行,SqlSessionFactoryBuilder类相当于一个操控台,将各方面的资源拿过来合成目标对象,Configuration类属于创建过程中一个重要的中间介质,
承载构建SqlSessionFactory所有配置,因为一个SqlSessionFactory是单例的,只能对应一个数据源,所以SqlSessionFactoryBuilder类再创建完SqlSessionFactory之后就是失去作用,被GC回收。
而Configuration类承载配置,还会在框架之后的流程中发挥作用。