MyBatis配置文件解析_属性节点properties的处理

properties子元素

properties子元素是MyBatis配置文件中的第一个子元素,用来指向一个属性文件,它在XML文件中的配置如下。

<properties resource="db.properties" url="路径">
    <!-- 可以定义自已的property -->
    <property name="db" value="mysql"></property>
    <property name="url" value="jdbc:mysql"></property>
</properties>

在mybatis初始化时,会读出resource或url指向的资源,保存到一个Properties对象中。Configuration对象有一个Property的属性variables,合并这两个Properties对象,保存到Configuration对象中,并下沉到其他所需的对象中,如XPathParser及XNode都保存了这个对象,以备用。

XMLConfigBuilder中解析properties子元素的方法

XMLConfigBuilder中解析properties子元素的方法是private void propertiesElement(XNode context),其代码与基本流程如下:

// 解析子元素properties代码
private void propertiesElement(XNode context) throws Exception {
  // 若配置文件中没有子标签**properties**则不作任何处理    
  if (context != null) {
    // 读出所有的property子标签,并读到一个属性(Properties)对象defaults  
    Properties defaults = context.getChildrenAsProperties();
    // 获得属性resource及url的值  
    String resource = context.getStringAttribute("resource");
    String url = context.getStringAttribute("url");
    // resource属性与url属性不能同时存在,若同时不空,则抛出异常**BuilderException**,可以同时为null
    if (resource != null && url != null) {
      throw new BuilderException("The properties element cannot specify both a URL and a resource based property file reference.  Please specify one or the other.");
    }
    // 获得resource或url中的资源表示的Properties对象,并合并到defaluts对象中  
    if (resource != null) {
      defaults.putAll(Resources.getResourceAsProperties(resource));
    } else if (url != null) {
      defaults.putAll(Resources.getUrlAsProperties(url));
    }
    // 若Configuration的vairables中已有值,一并合并到defaults中  
    Properties vars = configuration.getVariables();
    if (vars != null) {
      defaults.putAll(vars);
    }
    // 将完整的属性对象(Configuration中已有的属性对象,resource或url资源表示的属性对象,及properties下property对应的属性对象)
    // 保存到parser对象及configuration对象中  
    // XPathParser在解析属性值时,会处理${name},name对应的值中正是从这个variables中获取的  
    parser.setVariables(defaults);
    configuration.setVariables(defaults);
  }
}

Configuration属性variables的初值

初值可以从外部传入,即使用者传入,在调用SqlSessionFactoryBuilder的build方法时,客户可以传入一个Properties对象,作为Configuration属性variables的初值,具体代码如下:

// SqlSessionFactoryBuilder上的方法,客户可以传入一个Properties对象,这个对象会作为Configuration属性variables的初值
public SqlSessionFactory build(Reader reader, String environment, Properties properties) {
  try {
    //properties对象下沉到XMLConfigBuilder对象  
    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.
    }
  }
}
// XMLConfigBuilder构造方法
private XMLConfigBuilder(XPathParser parser, String environment, Properties props) {
    super(new Configuration());
    ErrorContext.instance().resource("SQL Mapper Configuration");
    // 这里将处部传入的属性对象作为Configuration的variables的初值
    this.configuration.setVariables(props);
    this.parsed = false;
    this.environment = environment;
    this.parser = parser;
}



posted @ 2022-04-13 13:29  beckwu  阅读(162)  评论(0)    收藏  举报