网站建设j基本步骤,湛江网站制作江网站制作,河南外贸网站建设,贵阳网络科技有限公司核心配置中${}表达式配置的解析一、核心配置主体二、核心配置文件中properties是如何被解析的#xff1f;三、${} 表达式的解析四、总结前提#xff1a;
核心配置文件是被XMLConfigBuilder 对象进行解析的#xff0c;configuration 对象是由它父类BaseBuider继承下来的属性…
核心配置中${}表达式配置的解析一、核心配置主体二、核心配置文件中properties是如何被解析的三、${} 表达式的解析四、总结前提
核心配置文件是被XMLConfigBuilder 对象进行解析的configuration 对象是由它父类BaseBuider继承下来的属性。
XMLConfigBuilder 对象解析完配置文件其信息是被封装在了configuration 对象中
然后返回通过SqlSessionFactoryBuilder 去通过buildconfiguration方法进行构建SqlSessionFactory对象
一个数据库是关联一个environment 的所以是一个sqlSessionFactory 对象对应一个数据库实际上也对应一个configuration 对象........一、核心配置主体
配置信息的配置主体先进行阐明
public Configuration parse() { if (parsed) { throw new BuilderException(Each XMLConfigBuilder can only be used once.); } parsed true; //源码中没有这一句只有 parseConfiguration(parser.evalNode(/configuration)); //为了让读者看得更明晰源码拆分为以下两句 XNode configurationNode parser.evalNode(/configuration); parseConfiguration(configurationNode); return configuration;
}
/** * 解析 /configuration节点下的子节点信息然后将解析的结果设置到Configuration对象中 */
private void parseConfiguration(XNode root) { try { //1.首先处理properties 节点 propertiesElement(root.evalNode(properties)); //issue #117 read properties first //2.处理typeAliases typeAliasesElement(root.evalNode(typeAliases)); //3.处理插件 pluginElement(root.evalNode(plugins)); //4.处理objectFactory objectFactoryElement(root.evalNode(objectFactory)); //5.objectWrapperFactory objectWrapperFactoryElement(root.evalNode(objectWrapperFactory)); //6.settings settingsElement(root.evalNode(settings)); //7.处理environments environmentsElement(root.evalNode(environments)); // read it after objectFactory and objectWrapperFactory issue #631 //8.database databaseIdProviderElement(root.evalNode(databaseIdProvider)); //9.typeHandlers typeHandlerElement(root.evalNode(typeHandlers)); //10.mappers mapperElement(root.evalNode(mappers)); } catch (Exception e) { throw new BuilderException(Error parsing SQL Mapper Configuration. Cause: e, e); }
} 再看核心配置文件中DTD约束不难看出其解析顺序和约束是一致的。这些解析出来的结果最后都会封装到configuration对象中。
二、核心配置文件中properties是如何被解析的
properties的三种配置方式
通过property 子标签进行namevalue进行配置通过url 属性外配置文件通过resource 属性外配置文件。为契合项目路径这种方式使用的多。
下面阅读已被吾注解好了的解析properties 的代码 private void propertiesElement(XNode context) throws Exception {if (context ! null) {// 第一种配置方式Properties defaults context.getChildrenAsProperties();// 第三种利用resource配置String resource context.getStringAttribute(resource);// 第二种利用url进行配置String url context.getStringAttribute(url);// 第二种和第三种配置不能同时存在// 意思就是resource 属性和 url 属性不能同时存在。// 如果同时存在的话就抛异常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进行判断了if (resource ! null) {defaults.putAll(Resources.getResourceAsProperties(resource));} else if (url ! null) {defaults.putAll(Resources.getUrlAsProperties(url));}// 这个是看原先有没有对cofiguration中的variables属性赋值// 如果有的话一并加入到defaults这个对象中Properties vars configuration.getVariables();if (vars ! null) {defaults.putAll(vars);}// parser 是一个XPathParser的对象其中有variable是其中的一个属性// variable 是Properties 对象// 先对parser 的variable的属性进行赋值后面用于 对datasource 的配置有用parser.setVariables(defaults);// 解析的结果最后得在configuration中所以....configuration.setVariables(defaults);}}这里需要注意的有两点
SqlSessionBuilder执行build方法的时候也是可以传一个Properties 对象的这个对象会在XMLConfigBuilder对象创建的时候赋值给configuration对象这也就是上面源码那个为什么要去判断一下有没有提前赋值上面的vars。这里defaults 对象虽然不允许 url 和 resource 属性值都时接受但是允许接受完 url 或 resource的配置文件后还可以加上第一种配置产生的值还可以接受 build 传过来的配置非常的灵活。Configuration 对象中的set、get方法是对外提供的当然也可以自行对其进行修改和获取。当然没啥事谁修改这玩意啊。
三、${} 表达式的解析
回到根本${} 到底是如何解析的呢
首先需要了解 XNode 类中的 evalNode(String expression) 方法。 这个 XPathParser 对象都是使用的 XMLConfigBuilder 内的属性 parser 对象。 variables 解析其他标签也都是共享的一级传一级的。
所以也就是说解析 datasource 是可以使用共享的 variables 的。
然后就可以看解析的 environmentElement 了看看。 解析这个 ${}‘ 的核心代码如下
/*** 这个类解析${}这种形式的表达式*/
public class PropertyParser {public static String parse(String string, Properties variables) {VariableTokenHandler handler new VariableTokenHandler(variables);GenericTokenParser parser new GenericTokenParser(${, }, handler);return parser.parse(string);}private static class VariableTokenHandler implements TokenHandler {private Properties variables;public VariableTokenHandler(Properties variables) {this.variables variables;}public String handleToken(String content) {if (variables ! null variables.containsKey(content)) {return variables.getProperty(content);}return ${ content };}}
}四、总结
解析顺序和DTD约束是一致的properties 配置的解析及其三种配置方式resource和url不可以共存但使用property子标签配置可以共存XMLConfigBuilder 中的 XPathParser 类型对象 parser 属性在解析过程中一直使用的是同一个并且所解析的 variables 那个配置也一直在传递variables 可以是properties 中所写的配置也可以是调用SqlSessionBuilder对象中的build方法进行传入${content} 是通过字符串处理的方式和从 variables 查询 content 的方式进行处理的。