Java多态实现统一日志格式策略的核心是解耦格式逻辑与打印行为:定义LogFormatter接口封装format方法,各实现类(Simple、Json、TraceAware)专注特定格式,LogPrinter门面依赖接口注入策略,支持运行时动态切换与开闭扩展。

Java 中利用多态实现统一日志输出格式策略,核心是把“日志格式怎么拼”这个逻辑从日志打印行为中解耦出来,交由不同实现类按需定制,而调用方只面向统一接口操作。
定义日志格式策略接口
声明一个描述“如何格式化日志内容”的接口,比如:
public interface LogFormatter {
String format(String level, String message, Throwable throwable, long timestamp);
}该接口只暴露一个方法,屏蔽具体格式细节。所有格式策略(如 JSON、纯文本、带 TraceID 的调试格式)都实现它。
提供多种格式策略实现类
每个实现类专注一种输出风格,例如:
立即学习“Java免费学习笔记(深入)”;
-
SimpleFormatter:输出
[INFO] 2024-05-20 10:30:45 - 用户登录成功 - JsonFormatter:生成标准 JSON 字符串,含 level、msg、time、stack 等字段
-
TraceAwareFormatter:自动注入 MDC 中的 traceId,格式为
[TRACE-abc123] ERROR ...
它们互不依赖,可独立测试、替换或组合(如装饰器模式增强)。
日志工具类或门面类依赖接口而非实现
封装一个日志门面(如 LogPrinter),构造时注入 LogFormatter,运行时完全不关心具体格式逻辑:
public class LogPrinter {
private final LogFormatter formatter;
<pre class="brush:php;toolbar:false;">public LogPrinter(LogFormatter formatter) {
this.formatter = formatter;
}
public void log(String level, String message, Throwable t) {
String formatted = formatter.format(level, message, t, System.currentTimeMillis());
System.out.println(formatted); // 或交给 slf4j/logback 实际输出
}}
切换格式只需更换构造参数:new LogPrinter(new JsonFormatter()),无需改任何日志调用代码。
运行时动态切换与扩展
可通过配置、SPI 或 Spring Bean 名称控制使用哪个策略:
- Spring 中用
@Qualifier("jsonFormatter")注入指定实现 - 通过工厂类根据环境变量返回对应 formatter 实例
- 支持策略链:如先做敏感信息脱敏,再转 JSON —— 用组合模式包装多个 formatter
新增格式只需加个新类 + 实现接口,老代码零修改,符合开闭原则。


















