你贴出的是一组 层层继承的 Maven 插件 Mojo 类 ,它们共同构成了 Apache Tomcat Maven Plugin(如 tomcat8-maven-plugin)中用于远程操作 Tomcat 的核心抽象体系。
我们可以从底向上理解这个设计:
🧱 第 1 层:Mojo 接口 ------ Maven 插件的契约
java
public interface Mojo {
void execute() throws MojoExecutionException, MojoFailureException;
void setLog(Log log);
Log getLog();
}
✅ 这是所有 Maven 插件目标(Goal)必须实现的接口。
execute():插件执行入口。getLog()/setLog():Maven 注入日志对象,用于输出信息。
🔹 这是 Maven 插件系统的"根接口"。
🧱 第 2 层:AbstractMojo ------ 基础实现类
java
public abstract class AbstractMojo implements Mojo {
private Log log;
public Log getLog() { ... }
public void setLog(Log log) { this.log = log; }
}
✅ 提供了 Mojo 接口的默认实现,特别是日志功能。
- 插件开发者只需继承它,就能直接使用
getLog().info(...)。 - 它还实现了
ContextEnabled,支持插件上下文(如共享数据)。
🔹 所有标准 Maven 插件都应继承此类。
🧱 第 3 层:AbstractTomcat8Mojo ------ Tomcat 插件通用基类
java
public abstract class AbstractTomcat8Mojo extends AbstractMojo {
@Parameter protected String path = "/${project.artifactId}";
protected String getPath() { return path; }
protected void checkTomcatResponse(...) { ... }
}
✅ 为所有 Tomcat 相关 Mojo 提供通用能力:
- 自动设置 Web 应用上下文路径(默认
/项目名)。 - 提供 HTTP 响应检查逻辑(状态码 ≥400 视为失败)。
- 注入了国际化消息提供者(
messagesProvider)和 Maven 设置(settings)。
🔹 这是 Tomcat 插件内部的"第一层抽象",不区分本地还是远程。
🧱 第 4 层:AbstractCatalinaMojo ------ 远程 Tomcat Manager 操作基类
java
public abstract class AbstractCatalinaMojo extends AbstractTomcat8Mojo {
// 认证相关参数:url, server, username, password...
// 核心方法:getManager(), getDeployedURL(), log()
@Override
public void execute() {
invokeManager(); // 调用子类具体逻辑
}
protected abstract void invokeManager(); // 子类必须实现
}
✅ 专用于与远程 Tomcat 的 manager/text API 交互:
- 支持三种认证方式(命令行 > settings.xml > 默认值)。
- 封装了
TomcatManager客户端。 - 使用 模板方法模式:父类控制流程,子类实现具体操作(如 deploy/undeploy)。
- 提供工具方法:
getDeployedURL()(生成应用访问地址)、log()(多行日志)。
🔹 这是 远程部署/管理类目标 (如
deploy,reload)的直接父类。
🧱 第 5 层:AbstractWarCatalinaMojo ------ WAR 项目专用校验层
java
public abstract class AbstractWarCatalinaMojo extends AbstractCatalinaMojo {
@Parameter private String packaging = "${project.packaging}";
@Parameter private boolean ignorePackaging = false;
@Override
public void execute() {
if (!isWar()) {
getLog().info("Skipping non-WAR project");
return; // 非 WAR 项目直接跳过
}
super.execute();
}
protected boolean isWar() {
return "war".equals(packaging) || ignorePackaging;
}
}
✅ 增加对项目打包类型的校验:
- 默认只处理
packaging=war的项目。 - 可通过
-Dtomcat.ignorePackaging=true强制忽略校验(用于特殊场景)。
🔹 这是为了防止用户误在 JAR、POM 等非 Web 项目上执行
tomcat8:deploy。
🌟 整体继承链总结
text
Mojo (接口)
↓
AbstractMojo (Maven 插件基础)
↓
AbstractTomcat8Mojo (Tomcat 通用配置)
↓
AbstractCatalinaMojo (远程 Tomcat Manager 操作)
↓
AbstractWarCatalinaMojo (WAR 项目校验)
↓
DeployMojo / UndeployMojo / ReloadMojo ... (具体目标实现)
💡 设计思想亮点
| 特性 | 说明 |
|---|---|
| 分层抽象 | 每一层只关注一个职责,高内聚低耦合 |
| 模板方法模式 | execute() → invokeManager(),流程固定,行为可扩展 |
| 认证策略灵活 | 支持命令行、settings.xml、默认值三层覆盖 |
| 安全防护 | 自动跳过非 WAR 项目,避免误操作 |
| 日志与国际化 | 统一消息管理,支持多语言(通过 messagesProvider) |
✅ 典型使用场景
当你运行:
bash
mvn tomcat8:deploy -Dtomcat.username=admin -Dtomcat.password=secret
实际调用栈是:
- Maven 启动
DeployMojo(继承自AbstractWarCatalinaMojo) - 检查项目是否为 WAR → 是
- 调用
AbstractCatalinaMojo.execute() - 加载认证信息(优先使用
-Dtomcat.username) - 创建
TomcatManager客户端 - 调用
DeployMojo.invokeManager()→ 执行部署 - 输出结果日志
📌 总结一句话
这组类通过五层继承,构建了一个高度复用、安全可靠、易于扩展的远程 Tomcat 操作框架,是 Maven 插件"面向抽象编程"和"分层设计"的典范。
如果你要开发类似的部署插件(比如对接 Jetty、WildFly),完全可以借鉴这种结构!