Tomcat8RunnerCli:可执行WAR的命令行门面

这段代码是 Tomcat8RunnerCli ------ 它是 Tomcat8Runner命令行接口(CLI)入口类,用于解析用户传入的参数,并启动内嵌 Tomcat。

你可以把它理解为:"可执行 WAR 文件的 main() 方法所在类" ,负责把命令行参数(如 -httpPort 9090)转换成 Java 对象配置,然后交给 Tomcat8Runner 去真正启动服务器。


🎯 一、核心作用

提供友好的命令行参数支持,让用户通过 java -jar app.war [options] 灵活控制内嵌 Tomcat 的行为。

例如:

bash 复制代码
java -jar myapp.war -httpPort 8081 -debug -Dmy.prop=value

🔧 二、关键组成部分解析

1. 使用 Apache Commons CLI 定义命令行选项

所有 Option 都通过 OptionBuilder 声明,比如:

java 复制代码
static Option httpPort = OptionBuilder
    .withArgName("httpPort")
    .hasArg()                  // 需要参数值
    .withDescription("http port to use")
    .create("httpPort");       // 长选项名

支持的选项包括:

选项 说明
-httpPort N HTTP 端口(默认由配置文件决定)
-httpsPort N HTTPS 端口
-ajpPort N AJP 端口
-serverXmlPath file 使用自定义 server.xml
-resetExtract 强制重新解压 WAR 内容
-Dkey=value 设置系统属性(类似 JVM 的 -D
-obfuscate password 直接混淆密码并退出 (调用 PasswordUtil.obfuscate()
-debug-X 启用调试日志
-help-h 打印帮助信息

✅ 这些选项覆盖了 Tomcat 启动所需的核心配置。


2. 优先级机制:命令行 > 配置文件

程序会先加载一个内置配置文件:

java 复制代码
// 从 JAR 内部读取 /tomcat.standalone.properties
Properties props = buildStandaloneProperties();

命令行参数优先级更高

java 复制代码
// 先读配置文件中的端口
port = props.getProperty(Tomcat8Runner.HTTP_PORT_KEY);
if (port != null) tomcat8Runner.httpPort = Integer.parseInt(port);

// 如果命令行指定了,则覆盖
if (line.hasOption(httpPort)) {
    tomcat8Runner.httpPort = Integer.parseInt(line.getOptionValue(httpPort));
}

💡 这是典型的"默认值 + 覆盖"设计模式。


3. 特殊功能:密码混淆工具

java 复制代码
if (line.hasOption(obfuscate)) {
    System.out.println(PasswordUtil.obfuscate(line.getOptionValue(obfuscate)));
    System.exit(0);
}

这意味着你可以这样使用:

bash 复制代码
java -jar myapp.war -obfuscate mypassword
# 输出:OBF:1v2j1uum1xtv1uvk1v0h1v2j

✅ 把可执行 WAR 当作一个 密码混淆工具 来用,非常方便!


4. 系统属性注入(-Dkey=value

java 复制代码
if (line.hasOption(sysProps)) {
    Properties sysProps = line.getOptionProperties('D');
    for (entry : sysProps) {
        System.setProperty(key, value); // 注入到 JVM 系统属性
    }
}

这让你可以:

bash 复制代码
java -jar app.war -Djavax.net.ssl.keyStore=keystore.jks -Dwars=app.war

→ 这些属性会被 Tomcat8Runner 读取(比如用于 HTTPS 或 WAR 列表)。


5. 帮助信息(HelpFormatter)

当参数错误或使用 -h 时,自动打印用法:

text 复制代码
usage: java -jar [path to your exec war jar]
 -ajpPort <ajpPort>               ajp port to use
 -clientAuth                      enable client authentication for https
 -debug                           debug
 -extractDirectory <extract...>   path to extract war content...
 -help                            help
 -httpPort <httpPort>             http port to use
 -httpsPort <httpsPort>           https port to use
 -obfuscate <password>            obfuscate the password and exit
 ...

🔄 三、整体工作流程(main() 方法)

  1. 解析命令行参数

    • 使用 GnuParser(支持 GNU 风格,如 -Dkey=value
    • 失败则打印帮助并退出
  2. 处理特殊命令

    • -help → 打印帮助
    • -obfuscate xxx → 混淆密码并退出
  3. 加载默认配置

    • 从 JAR 内部的 tomcat.standalone.properties 读取默认值
  4. 应用命令行覆盖

    • 将 CLI 参数赋值给 Tomcat8Runner 实例
  5. 启动 Tomcat

    java 复制代码
    tomcat8Runner.run(); // 进入真正的启动逻辑

📦 四、与 Tomcat8Runner 的关系

职责
Tomcat8RunnerCli 命令行解析 + 配置组装(面向用户)
Tomcat8Runner 实际启动 Tomcat + 部署应用(面向运行)

✅ 分离关注点:CLI 只负责"怎么启动",Runner 负责"启动什么"。

在构建可执行 WAR 时,Maven 插件会设置:

xml 复制代码
<Main-Class>Tomcat8RunnerCli</Main-Class>

所以 java -jar app.war 实际执行的是 Tomcat8RunnerCli.main()


✅ 五、典型使用场景

场景 1:快速启动 Web 应用

bash 复制代码
java -jar myapp-exec.war -httpPort 9090

场景 2:生成混淆密码

bash 复制代码
java -jar myapp-exec.war -obfuscate admin123
# 得到 OBF:xxx,用于配置文件

场景 3:调试部署问题

bash 复制代码
java -jar myapp.war -debug -resetExtract

场景 4:启用 HTTPS

bash 复制代码
java -jar myapp.war \
  -httpsPort 8443 \
  -Djavax.net.ssl.keyStore=keystore.jks \
  -Djavax.net.ssl.keyStorePassword=secret

🧠 总结:一句话理解

Tomcat8RunnerCli 是可执行 WAR 的"命令行门面",它将用户输入的参数转化为结构化配置,驱动内嵌 Tomcat 启动,同时提供密码混淆等实用工具功能。

它是 传统 WAR 应用实现"单文件交付 + 灵活配置"体验的关键一环,让 Java Web 应用像脚本一样简单运行。

如果你正在使用 Maven 的 tomcat7-maven-pluginexec-war 目标,那么你生成的可执行 WAR 就是靠这个类来启动的!

相关推荐
人道领域7 小时前
SSM框架从入门到入土(SpringFrameWork)
java·spring boot·tomcat
belldeep10 小时前
Java:Tomcat 9 和 mermaid.min.js 10.9 上传.csv文件实现 Markdown 中 Mermaid 图表的渲染
java·tomcat·mermaid·去除flexmark
lang2015092810 小时前
Tomcat Maven插件:部署与卸载的架构设计
java·tomcat·maven
lang2015092811 小时前
Tomcat Maven插件全解析:开发部署一体化
java·tomcat·maven
tb_first12 小时前
万字超详细苍穹外卖学习笔记3
java·jvm·笔记·学习·spring·tomcat·maven
lang2015092814 小时前
Tomcat Maven插件核心设计解析
tomcat·maven·firefox
计算机学姐14 小时前
基于SpringBoot的校园流浪动物救助平台
java·spring boot·后端·spring·java-ee·tomcat·intellij-idea
lang2015092814 小时前
一键生成Java Web项目:Tomcat-Maven原型解析
java·前端·tomcat
lang2015092814 小时前
Tomcat Maven插件运行WAR包解析
tomcat·maven·firefox