Hasor 的 Xml 配置文件解析详解

    我以为 Xml 做为配置文件最大的好处是结构化,对程序配置信息能够有结构有组织的进行描述。可是使用 Xml 做为配置文件带给咱们的问题是咱们须要程序本身去解析Xml配置文件结构。这显得有点多余且啰嗦。 java

    所以一般咱们的配置文件都使用 java 提供的属性文件,属性文件虽然没有 Xml 文件那样清晰的结构化,但只要标注好注释属性文件仍是能够胜任这份工做的。 node

    Hasor 使用 Xml 做为其配置文件,可是能够像属性文件同样去访问它。 web

    首先 Hasor 会将 Xml 片断映射成一组 Map 的 key/value 键值对,以下: sql

<?xml version="1.0" encoding="UTF-8"?>
<config xmlns="http://project.hasor.net/hasor/schema/main">
  <!-- Demo 项目源码所处包 -->
  <hasor debug="false">
    <loadPackages>net.test.project.*</loadPackages>
  </hasor>
</config>
hasor              = <...>
hasor.debug        = <...>
hasor.loadPackages = <...>

    你们可能有点摸不清头脑是怎样一种规则,下面我就来介绍一下 Hasor 配置文件的映射规则。 数据库

    以 XPath 为例,当咱们须要访问"<hasor>"节点时候,可使用“hasor”这个表达式。若是须要获取"<loadPackages>"节点的话使用“hasor/loadPackage”这个表达式。 app

    Hasor 的规则与其类似。Hasor 在创建节点映射关系时会将其 XPath 做为生成 key 的依据。不一样于 XPath 的是 hasor 使用“.”分割。例如:loadPackage节点的映射关系是“hasor.loadPackage”。 框架

    若是要想取得 Xml 配置文件中 debug 这个属性的值,一般 Xpath 的表达式为“hasor/@debug”,在 hasor 中属性的映射会变为:“hasor.debug”。或许有的同窗会以为若是有一个名为“debug”的 xml 元素位于 hasor 元素下岂不是会出现冲突? 分布式

    没错在 Hasor 的映射规则下会出现冲突,并且只会有一个有效。Hasor 设计统一配置文件读取策略的目的并非为了取代 XPath,而是提供一种便捷的 Xml 配置文件获取方式。 工具

    举一个比较复杂的例子的映射关系,下面这段 Xml 取自Demo程序的配置文件,它配置了Demo程序使用的数据库链接信息: 性能

<?xml version="1.0" encoding="UTF-8"?>
<config xmlns="http://project.hasor.net/hasor/schema/main">
  <!-- 数据源配置 -->
  <hasor-jdbc>
    <dataSourceSet default="localDB">
      <!-- 名称为 localDB 的内存数据库,数据库引擎使用 HSQL -->
      <dataSource name="localDB" dsFactory="net.hasor.plugins.datasource.factory.C3p0Factory">
        <driver>org.hsqldb.jdbcDriver</driver>
        <url>jdbc:hsqldb:mem:aname</url>
        <user>sa</user>
        <password></password>
      </dataSource>
    </dataSourceSet>
  </hasor-jdbc>
</config>

    对于上面这段 Xml 若是我要取得数据库链接的用户名"sa",须要使用这个映射 key:“hasor-jdbc . dataSourceSet . dataSource . user”,能够看到取得某个元素的值其实就是经过元素名一路“.”下去的。

    若是我要取得的是 dsFactory 属性信息,可使用这个映射 key:“hasor-jdbc . dataSourceSet . dataSource . dsFactory”。

    你们能够看出,其实 Hasor 在映射时 xml 属性会被认为是元素的子元素,换句话说,上面这段配置文件能够改成下面这种写法:

<?xml version="1.0" encoding="UTF-8"?>
<config xmlns="http://project.hasor.net/hasor/schema/main">
  <hasor-jdbc>
    <dataSourceSet>
      <default>localDB</default>
      <dataSource>
        <name>localDB</name>
        <dsFactory>net.hasor.plugins.datasource.factory.C3p0Factory</dsFactory>
        <driver>org.hsqldb.jdbcDriver</driver>
        <url>jdbc:hsqldb:mem:aname</url>
        <user>sa</user>
        <password></password>
      </dataSource>
    </dataSourceSet>
  </hasor-jdbc>
</config>

1.性能

    上面介绍了 Hasor 的配置文件映射规则,下面解释一下 Hasor 配置文件读取机制。

    初一看可能有的同窗会以为,Hasor 在读取配置文件时或许采用了 XPath 表达式进行读取。若是遇到频繁访问时性能会极具降低。

    我能够告诉你们,Hasor 考虑到 XPath 性能的问题,所以它内部并非经过 XPath 进行解析,而是使用 Map进行映射。

    Hasor 在启动时会调用 Sax 方式扫描整个 Xml 文件,而后在扫描过程当中持续的生成 Key/Value 键值对,这些键值对最后会保存到一个 Map 中,咱们取得的全部配置文件信息最后都会在这个Map中去查找。

    正由于这种方式 Hasor 的配置文件读取速度不会输给属性文件。

2.覆盖问题

    因为 Hasor 的映射规则 Hasor 的配置文件在生成最终 Map 时会产生 key 覆盖问题。前面已经提到了一种覆盖现象,属性名和子元素名同名状况下就会出现覆盖。

    此外同名子元素也会存在 key 覆盖问题,这些问题是 hasor 映射规则没法解决的。而且 Hasor 的映射规则也不会力争去解决这个问题,由于 Hasor 的配置映射规则并不打算成为另一个 XPath。

    覆盖问题虽然会出现,可是 Hasor 却提供了一种办法解决它。

3.DOM 方式读取 Xml

    即便 Hasor 经过 Map 方式创建的映射,而且也是经过 Map 方式获取节点。可是这并不能阻拦 Haso 为您提供一套 DOM 方式获取内容的途径。

    各位或许以为经过 DOM 方式会引起 Hasor 重载配置文件,或者说 Hasor 内部除了 Map 映射还保留了另一个 DOM树。那么您就大错特错了!

    Hasor 存储 Xml 映射信息只有 Map 这一种途径,Hasor 不会浪费多余的内存空间。Hasor 在保存映射时它为每个 Xml 映射节点都使用 XmlNode 接口进行封装。

    大到一个 Xml 元素,小到一个 Xml 属性。凡是 Xml 中可到达的元素都是经过这个对象进行封装。

    若是 XmlNode 表示的是一个元素,那么这个对象的 children 属性中就保存了它的全部子节点,而 arrMap 属性保存的就是这个元素的全部属性。所以咱们只要经过映射 key 取得 XmlNode 接口便可。

    这样一来就能够在不增长内存开销的状况下增长 DOM 方式读取配置文件。

    例以下面这个 Xml 例子:

<?xml version="1.0" encoding="UTF-8"?>
<config xmlns="http://project.hasor.net/hasor/schema/main">
  <demoProject>
    <menus>
      <menu code="FunA" name="功能演示A" url="/funa" />
      <menu code="FunB" name="功能演示B" url="/funb" />
      <menu code="UserMgr" name="用户管理" url="/mgr/user/userList.do" />
    </menus>
  </demoProject>
</config>

    解析上面这段 Xml 将它的 menu 元素信息保存到 List 中:

List<MenuBean> menuList = new ArrayList<MenuBean>();
/*获取操纵配置文件的接口*/
Settings setting = appContext.getSettings();
/*取得‘/demoProject/menus’ Xml节点*/
XmlNode xmlNode = setting.getXmlProperty("demoProject.menus");
/*使用 DOM 方式解析 Xml节点*/
List<XmlNode> menus = xmlNode.getChildren("menu");
for (XmlNode node : menus) {
    MenuBean menuBean = new MenuBean();
    menuBean.setCode(node.getAttribute("code"));
    menuBean.setName(node.getAttribute("name"));
    menuBean.setUrl(node.getAttribute("url"));
    menuList.add(menuBean);
}

4.关于根节点

    Hasor 的配置文件默认是不映射根节点的,若是开发者须要获取根节点则须要经过映射 key“.”取得。当配置文件中存在多个命名空间定义状况下,根节点也会出现多个。换句话说根节点是针对 Xml 命名空间的而非 Xml 文件内容自己。

5.命名空间

    Hasor 要求被解析的 Xml 文件必须有一个命名空间,命名空间地址能够是任意的。这就意味着您能够同时装载两个不一样命名空间下的 Xml 配置文件,而且随意读取它们。Hasor 目前已经在使用的命名空间以下:

  1. 主配置文件:http://project.hasor.net/hasor/schema/main
  2. Hasor-Core:http://project.hasor.net/hasor/schema/hasor-core
  3. Hasor-Web:http://project.hasor.net/hasor/schema/hasor-web
  4. Hasor-JDBC:http://project.hasor.net/hasor/schema/hasor-jdbc

    Hasor 的 Xml 解析支持多个命名空间会给程序带来很大的意义。比方说咱们为每一个不一样的业务模块都设立一个命名空间,而后不一样业务模块的开发交给不一样的开发小组完成。最后在合并这些开发小组所产生的配置文件。

    一般咱们会统一维护配置文件,谁修改了配置文件他就立刻递交。后来者在修改时须要及时更新一下看看是否有更改。当开发小组成员比较集中的时候,这种办法勉强是不会出现问题的。

    若是开发小组的成员不常常在一块儿,这种统一式的管理变得不那么靠谱。尤为在异地开发模式中显得更加突出。即便是经过属性文件维护程序的配置文件也会面对这个问题。

    在这种场景下,通常咱们可能会写好多个属性配置文件。而后在分别用不一样的 map 载入它们统一管理。虽然能够解决问题,可是我以为这并不优雅。

    Hasor 的配置文件能够经过命名空间对业务模块加以区分,不一样的业务模块当使用配置文件时从本身的命名空间中取值,不影响其它模块。这样一来既能能够很好控制冲突的发生,又能统一维护配置文件。

    一般通常状况下一个模块一般也是由一个小组来完成,这样更加能够确保冲突的发生几率。重而很好的知足 分布式开发 的需求。

    例以下面配置文件代码:

<?xml version="1.0" encoding="UTF-8"?>
<config xmlns:mod1="http://mode1.myProject.net" xmlns:mod2="http://mode2.myProject.net" xmlns="http://project.hasor.net/hasor/schema/main">
  <!-- mode1 配置 -->
  <mod1:config>
    <mod1:appSettings>
      <mod1:serverLocal mod1:url="www.126.com" />
    </mod1:appSettings>
  </mod1:config>
  <!-- mode2 配置 -->
  <mod2:config>
    <mod2:appSettings>
      <mod2:serverLocal mod2:url="www.souhu.com" />
    </mod2:appSettings>
  </mod2:config>
</config>

    在这个配置文件中实际上是定义了三个命名空间,之因此这样写的目的是为了看起来更加直观。下面是测试代码:

File inFile = new File("ns-config.xml");
FileSettings settings = new FileSettings(inFile);
//
//Mode1
Settings mod1 = settings.getSetting("http://mode1.myProject.net");
Settings mod2 = settings.getSetting("http://mode2.myProject.net");

System.out.println(mod1.getString("appSettings.serverLocal.url"));
System.out.println(mod2.getString("appSettings.serverLocal.url"));

    在多个命名空间下 Hasor 的配置文件解析会为每一个命名空间的元素都创建一个根节点。

6.多配置文件同时加载

    为了更加方便协做开发,Hasor 的 Xml 配置文件解析机制还支持多个配置文件同时加载。

    加载的不一样配置中文件会出现 冲突问题 ,Hasor 当遇到冲突时采用的 内容覆盖&合并 机制。

    例如:若是遇到相同映射 key 的元素,Hasor 会使用新的元素内容覆盖已存在的元素内容。新元素的子元素和属性会按照顺序追加到已有老元素的 children 和 attrMap 中。

    可是这种合并不会将两个不一样命名空间下的冲突元素合并到一块儿。它们会被保存在彼此隔离的两个不一样 Map 中。这个 Map 是在映射 key/value 键值对的上层创建的一个命名空间 Map。这个结构是Map<String,Map<String,String>> 结构。

    因此说若是加载的两个配置文件虽然有相同的属性映射 key ,但处于不一样命名空间下。Hasor 的配置文件加载不会认为它们是冲突的,您使用上面的代码仍然能够读取到位于两个配置文件中的不一样配置。例如:

------ns1-config.xml

<?xml version="1.0" encoding="UTF-8"?>
<config xmlns="http://mode1.myProject.net">
  <appSettings>
    <serverLocal url="www.126.com" />
  </appSettings>
</config>

------ns2-config.xml

<?xml version="1.0" encoding="UTF-8"?>
<config xmlns="http://mode2.myProject.net">
  <appSettings>
    <serverLocal url="www.souhu.com" />
  </appSettings>
</config>

 程序代码以下:

File inFile1 = new File("ns1-config.xml");
File inFile2 = new File("ns2-config.xml");
FileSettings settings = new FileSettings();
settings.addFile(inFile1);
settings.addFile(inFile2);
settings.refresh();
//
Settings mod1 = settings.getSetting("http://mode1.myProject.net");
Settings mod2 = settings.getSetting("http://mode2.myProject.net");
System.out.println(mod1.getString("appSettings.serverLocal.url"));
System.out.println(mod2.getString("appSettings.serverLocal.url"));

7.“static-config.xml”和“hasor-config.xml”

   Hasor 的配置文件按照做用分为两种,它们分别用于不一样的场景。static-config.xml 配置文件一般是伴随hasor软件包一同发布的。您能够在:Hasor-Core、Hasor-Web、Hasor-JDBC 它们的 jar 包中找到它们的身影。

    “static-config.xml”顾名思义静态配置,意思就是说这些配置文件内容是不能够被改变的。且文件名也是固定的,这也包括了它们的存放位置。

    一般静态配置文件中保存的是默认配置,在软件开发中通常不会涉及到编写一个“static-config.xml”。固然若是您的软件中有不少配置信息不想暴露给实施人员,能够考虑将这些配置项目放到static-config.xml中。

    Hasor 在启动时候会先加载位于 classpath 中全部指定目录中的 static-config.xml,而且按照前面说的逻辑进行处理。static-config.xml 的加载顺序取决于 jar 包扫描顺序,因为具体环境的复杂性,您能够认为它们的加载顺序是不可靠的。

    在接触 Hasor 的配置文件时,常常被说起的是 hasor-config.xml 。它被成为主配置文件,做为主配置文件它的内容是最高优先级的。它的加载是在 static-config.xml 加载完成以后,这样能够确保 hasor-config.xml 的内容覆盖默认配置。

    此外,Hasor 的配置文件系统还会监控主配置文件是否在运行期发生了改变。若是发生改变,Hasor 会重载这个配置文件,而后经过 SettingsListener 接口通知配置文件重载了。

    开发者可使用 SettingsListener 接口开发出动态修改配置文件内容而让程序自动感知的效果,Hasor-Core 中绝大部分配置都是支持 及时修改及时生效的。而 Hasor-Web 和 Hasor-JDBC 中的配置却不支持及时修改及时生效。

8.工具类及层次结构

    图中蓝色部分表示接口,灰色部分表示类。Hasor 的整个配置文件服务类的层次关系如上图所示。

    AbstractSettings 该类主要的目的是抽象出 key/value 数据容器(Map)。并基于这个容器实现大部分 Settings 接口中的方法

    AbstractBaseSettings 抽象类是基于 AbstractSettings 的功能对数据容器提供了命名空间区分支持,该类实现了 getSetting(namespace) 接口方法和 getSettingArray 接口方法。

    InputStreamSettings 类是全部基于流形式加载配置文件的基类,该类实现了 IOSettings 接口。而且经过 loadSettings 方法实现配置文件加载。也是该类提供了基于 Sax 下的 Xml 配置文件解析支持,这部分代码位于 SaxXmlParser 类中。该类还支持多个 InputStream 的顺序解析。

    FileSettings 是一个独立的 Hasor 配置文件解析服务类,第六小节已经展现了如何使用它。

    StandardContextSettings 该类是 Hasor 配置文件体系所使用的工具类,该类提供了“static-config.xml”和“hasor-config.xml”配置文件的加载支持。

    第7小节所阐述的配置文件修改监听器功能,是由 Environment 部分提供的,本文暂不说起。

-------------------------------

    以上就是 Hasor 配置文件解析的主要内容,因为篇幅的关系。有关扩展部分留在之后在介绍。

    在最后,不少同窗看完以后可能以为 Hasor 的配置文件体系,彷佛有点超越配置文件自己所作的事情。的确是这样,由于 Hasor 须要为开发者提供基于 Xml 下统一的最简化的配置文件解析服务。所以不少方面都须要考虑周全,所以才有的这个规模。

    最后奉献上 Hasor 配置文件接口的定义供你们欣赏,最后祝你们工做愉快,元旦快乐。

public interface Settings {
    //在框架扫描包的范围内查找具备特征类集合。(特征能够是继承的类、标记某个注解的类)
    public Set<Class<?>> getClassSet(Class<?> featureType, String[] loadPackages);
    //在框架扫描包的范围内查找具备特征类集合。(特征能够是继承的类、标记某个注解的类)
    public Set<Class<?>> getClassSet(Class<?> featureType, String loadPackages);
    //获取指在某个特定命名空间下的Settings接口对象。
    public String[] getSettingArray();
    //获取指在某个特定命名空间下的Settings接口对象。
    public Settings getSetting(String namespace);
    //强制从新装载配置文件。
    public void refresh() throws IOException;
    //
    //解析全局配置参数,而且返回其{@link Character}形式对象。
    public Character getChar(String name);
    //解析全局配置参数,而且返回其{@link Character}形式对象。第二个参数为默认值。
    public Character getChar(String name, Character defaultValue);
    //解析全局配置参数,而且返回其{@link String}形式对象。
    public String getString(String name);
    //解析全局配置参数,而且返回其{@link String}形式对象。第二个参数为默认值。
    public String getString(String name, String defaultValue);
    //解析全局配置参数,而且返回其{@link Boolean}形式对象。
    public Boolean getBoolean(String name);
    //解析全局配置参数,而且返回其{@link Boolean}形式对象。第二个参数为默认值。
    public Boolean getBoolean(String name, Boolean defaultValue);
    //解析全局配置参数,而且返回其{@link Short}形式对象。
    public Short getShort(String name);
    //解析全局配置参数,而且返回其{@link Short}形式对象。第二个参数为默认值。
    public Short getShort(String name, Short defaultValue);
    //解析全局配置参数,而且返回其{@link Integer}形式对象。
    public Integer getInteger(String name);
    //解析全局配置参数,而且返回其{@link Integer}形式对象。第二个参数为默认值。
    public Integer getInteger(String name, Integer defaultValue);
    //解析全局配置参数,而且返回其{@link Long}形式对象。
    public Long getLong(String name);
    //解析全局配置参数,而且返回其{@link Long}形式对象。第二个参数为默认值。
    public Long getLong(String name, Long defaultValue);
    //解析全局配置参数,而且返回其{@link Float}形式对象。
    public Float getFloat(String name);
    //解析全局配置参数,而且返回其{@link Float}形式对象。第二个参数为默认值。
    public Float getFloat(String name, Float defaultValue);
    //解析全局配置参数,而且返回其{@link Double}形式对象。
    public Double getDouble(String name);
    //解析全局配置参数,而且返回其{@link Double}形式对象。第二个参数为默认值。
    public Double getDouble(String name, Double defaultValue);
    //解析全局配置参数,而且返回其{@link Date}形式对象。
    public Date getDate(String name);
    //解析全局配置参数,而且返回其{@link Date}形式对象。第二个参数为默认值。
    public Date getDate(String name, Date defaultValue);
    //解析全局配置参数,而且返回其{@link Date}形式对象。第二个参数为默认值。
    public Date getDate(String name, long defaultValue);
    //解析全局配置参数,而且返回其{@link Date}形式对象。
    public Date getDate(String name, String format);
    //解析全局配置参数,而且返回其{@link Date}形式对象。第二个参数为默认值。
    public Date getDate(String name, String format, Date defaultValue);
    //解析全局配置参数,而且返回其{@link Date}形式对象。第二个参数为默认值。
    public Date getDate(String name, String format, long defaultValue);
    //解析全局配置参数,而且返回其{@link Enum}形式对象。第二个参数为默认值。
    public <T extends Enum<?>> T getEnum(String name, Class<T> enmType);
    //解析全局配置参数,而且返回其{@link Enum}形式对象。第二个参数为默认值。
    public <T extends Enum<?>> T getEnum(String name, Class<T> enmType, T defaultValue);
    //解析全局配置参数,而且返回其{@link Date}形式对象(用于表示文件)。第二个参数为默认值。
    public String getFilePath(String name);
    //解析全局配置参数,而且返回其{@link Date}形式对象(用于表示文件)。第二个参数为默认值。
    public String getFilePath(String name, String defaultValue);
    //解析全局配置参数,而且返回其{@link File}形式对象(用于表示目录)。第二个参数为默认值。
    public String getDirectoryPath(String name);
    //解析全局配置参数,而且返回其{@link File}形式对象(用于表示目录)。第二个参数为默认值。
    public String getDirectoryPath(String name, String defaultValue);
    //解析全局配置参数,而且返回其{@link XmlNode}形式对象。
    public XmlNode getXmlProperty(String name);
    //
    //解析全局配置参数,而且返回其{@link Character}形式对象。
    public Character[] getCharArray(String name);
    //解析全局配置参数,而且返回其{@link Character}形式对象。第二个参数为默认值。
    public Character[] getCharArray(String name, Character defaultValue);
    //解析全局配置参数,而且返回其{@link String}形式对象。
    public String[] getStringArray(String name);
    //解析全局配置参数,而且返回其{@link String}形式对象。第二个参数为默认值。
    public String[] getStringArray(String name, String defaultValue);
    //解析全局配置参数,而且返回其{@link Boolean}形式对象。
    public Boolean[] getBooleanArray(String name);
    //解析全局配置参数,而且返回其{@link Boolean}形式对象。第二个参数为默认值。
    public Boolean[] getBooleanArray(String name, Boolean defaultValue);
    //解析全局配置参数,而且返回其{@link Short}形式对象。
    public Short[] getShortArray(String name);
    //解析全局配置参数,而且返回其{@link Short}形式对象。第二个参数为默认值。
    public Short[] getShortArray(String name, Short defaultValue);
    //解析全局配置参数,而且返回其{@link Integer}形式对象。
    public Integer[] getIntegerArray(String name);
    //解析全局配置参数,而且返回其{@link Integer}形式对象。第二个参数为默认值。
    public Integer[] getIntegerArray(String name, Integer defaultValue);
    //解析全局配置参数,而且返回其{@link Long}形式对象。
    public Long[] getLongArray(String name);
    //解析全局配置参数,而且返回其{@link Long}形式对象。第二个参数为默认值。
    public Long[] getLongArray(String name, Long defaultValue);
    //解析全局配置参数,而且返回其{@link Float}形式对象。
    public Float[] getFloatArray(String name);
    //解析全局配置参数,而且返回其{@link Float}形式对象。第二个参数为默认值。
    public Float[] getFloatArray(String name, Float defaultValue);
    //解析全局配置参数,而且返回其{@link Double}形式对象。
    public Double[] getDoubleArray(String name);
    //解析全局配置参数,而且返回其{@link Double}形式对象。第二个参数为默认值。
    public Double[] getDoubleArray(String name, Double defaultValue);
    //解析全局配置参数,而且返回其{@link Date}形式对象。
    public Date[] getDateArray(String name);
    //解析全局配置参数,而且返回其{@link Date}形式对象。第二个参数为默认值。
    public Date[] getDateArray(String name, Date defaultValue);
    //解析全局配置参数,而且返回其{@link Date}形式对象。第二个参数为默认值。
    public Date[] getDateArray(String name, long defaultValue);
    //解析全局配置参数,而且返回其{@link Date}形式对象。
    public Date[] getDateArray(String name, String format);
    //解析全局配置参数,而且返回其{@link Date}形式对象。第二个参数为默认值。
    public Date[] getDateArray(String name, String format, Date defaultValue);
    //解析全局配置参数,而且返回其{@link Date}形式对象。第二个参数为默认值。
    public Date[] getDateArray(String name, String format, long defaultValue);
    //解析全局配置参数,而且返回其{@link Enum}形式对象。第二个参数为默认值。
    public <T extends Enum<?>> T[] getEnumArray(String name, Class<T> enmType);
    //解析全局配置参数,而且返回其{@link Enum}形式对象。第二个参数为默认值。
    public <T extends Enum<?>> T[] getEnumArray(String name, Class<T> enmType, T defaultValue);
    //解析全局配置参数,而且返回其{@link Date}形式对象(用于表示文件)。第二个参数为默认值。
    public String[] getFilePathArray(String name);
    //解析全局配置参数,而且返回其{@link Date}形式对象(用于表示文件)。第二个参数为默认值。
    public String[] getFilePathArray(String name, String defaultValue);
    //解析全局配置参数,而且返回其{@link File}形式对象(用于表示目录)。第二个参数为默认值。
    public String[] getDirectoryPathArray(String name);
    //解析全局配置参数,而且返回其{@link File}形式对象(用于表示目录)。第二个参数为默认值。
    public String[] getDirectoryPathArray(String name, String defaultValue);
    //解析全局配置参数,而且返回其{@link XmlNode}形式对象。
    public XmlNode[] getXmlPropertyArray(String name);
}
相关文章
相关标签/搜索