JFinal-Undertow 配置文件工作原理

时间:2021-03-25     访问量:1614

所属栏目:知识库

1. 默认配置文件

首先要从 UndertowServer 说起,UndertowServer 有多个创建方法,不管使用哪个创建方法最终创建时创建时都需要先创建 UndertowConfig,并将这个作为参数用于创建 UndertowServer。源码摘取如下:

/**
 * 创建 UndertowServer
 * 
 * 尝试使用 "undertow.txt" 以及 "undertow-pro.txt" 初始化 undertow
 * 当配置文件不存在时不抛出异常而是使用默认值进行初始化
 */
public static UndertowServer create(Class jfinalConfigClass) {
    return new UndertowServer(new UndertowConfig(jfinalConfigClass));
}

同样的 UndertowConfig 也有多个创建方法,不管使用哪个创建方法最终创建时都是需要进行配置文件的加载和配置项的初始化,当指定配置文件名根据指定的配置文件进行加载,未指定配置文件名时将加载默认的配置文件 undertow.txt,并进行参数赋值。源码摘取如下:

public UndertowConfig(String jfinalConfigClass) {
    this.jfinalConfig = jfinalConfigClass;
    //这里未指定参数文件使用默认的undertow.txt
    p = createPropExt(UNDERTOW_CONFIG);
    if (p.notEmpty()) {
        init();
    }
}

2. 生产版本配置文件

JFinal-Undertow 将会自动尝试加载生产版本的配置文件,可以根据默认配置文件或者指定的配置文件自动获取生产版本的配置文件,源码摘取如下:

/**
 * 假定用户创建 UndertowServer 时指定 undertow 的配置文件为 abc.txt
 * 或者 abc-dev.txt 或者 abc_dev.txt,例如:
 *     UndertowServer.create(AppConfig.class, "abc.txt").start();
 * 
 * 尝试加载 abc-pro.txt 便于在 fatjar 模式下以 config 目录中通过创建
 * abc-pro.txt 配置文件覆盖打包在 jar 包中的 abc-dev.txt 配置
 */
protected String buildUndertowConfigPro(String undertowConfig) {
    int index = undertowConfig.lastIndexOf('.');
    if (index > 0) {
        String main = undertowConfig.substring(0, index);
        main = removeDevEnds(main);
        String ext = undertowConfig.substring(index);
        return main + "-pro" + ext;
    } else {
        return removeDevEnds(undertowConfig) + "-pro";
    }
}

3. 配置项默认值

配置文件中的所有项在 UndertowConfig 中都是有默认值得,当没有任何一个配置文件时也就是使用这些默认值了,多数默认值都是 null,有效的几个如下:

// 开发模式才支持热加载,此配置与 jfinal 中的是不同的用途
protected volatile static boolean devMode = false;
protected int port = 80;
protected String host = "0.0.0.0";
protected String contextPath= "/";
// web 资源路径
protected String resourcePath = "src/main/webapp, WebRoot, WebContent";
protected int gzipMinLength = 1024;

4. web 资源加载路径配置

jfinal undertow 可以十分方便地从文件系统的目录以及 class path 或 jar 包中加载 web 静态资源,以下是配置示例:

undertow.resourcePath = src/main/webapp, classpath:static

如上所示 "src/main/webapp" 表示从项目根目录下的 "src/main/webapp" 下去加载 web 静态资源。 "classpath:static" 表示从 class path 以及 jar 包中的 static 路径下去加载 web 静态资源。

undertow.resourcePath 配置的另一个重点是,以 "classpath:" 为前缀的配置需要自行注意路径是否存在,尽可能只配置存在的路径。而不以 "classpath:" 打头的配置可以将开发与部署时的路径一起配置进来(逗号分隔开),jfinal undertow 会在运行时检测路径是否存在,存在才真正让其生效,从而很方便一次配置同时适用于开发、生产两种环境。

重要:PathKit.getWebRootPath() 将指向 undertow.resourcePath 配置中的第一个有效目录,而 configEngine(Engine engine) 方法中的 engine 对象已被默认配置了 engine.setBaseTemplatePath(PathKit.getWebRootPath())。所以该配置与 engine 的 baseTemplatePath 有关联。

 

实际测试信息记录如下:

JFinal.initPathKit() 中的 servletContext.getRealPath("/"); 获取到的值,取决于 undertow.resourcePath,使用的是第一个有效目录;

根据代码观察应该是在 UndertowServer.configUndertow 中使用 di.setResourceManager(config.getResourceManager()); 逻辑将 undertow.resourcePath 和 servletContext 做了关联;

分别在 UndertowServer.start、UndertowServer.doStart、MyConfig.onStart方法中输出了多次 PathKit.getWebRootPath,控制台显示的输出顺序是在 onStart 方法前后都有输出,但是仅有 onStart 方法中输出的信息是在 undertow.txt 中配置的,UndertowServer.start、UndertowServer.doStart 都不是配置中的,这应该就是波总说的时机不对吧,但是能力有限不能很好地理解这个时机。