SLF4J 中的适配器模式
什么是适配器模式
适配器模式中,适配器包装不兼容指定接口的对象,来实现不同兼容指定接口。
SLF4J 中的适配器模式
SLF4J 是一个日志门面系统,其中提供了统一的 Logger 等接口,许多框架都会面向 SLF4J 打印日志,这样就不会和具体的日志框架耦合在一起,框架使用者也就能够很方便地在不同日志实现之间切换。
SLF4J 出现之前,已经有 Log4j 等日志框架了,其本身有一套 Logger 之类的接口,为实现和 SLF4J 兼容,就引入了对应适配器层 slf4j-log4j12。
首先看一下 SLF4J 中的 Logger 接口:
public interface Logger { String getName(); void debug(String msg); void info(String msg); void warn(String msg); void error(String msg); // ...省略其他方法 }
而待适配的 Log4j 的 Logger 部分源码如下:
public class Logger extends Category { protected Logger(String name) { super(name); } public static Logger getLogger(String name) { return LogManager.getLogger(name); } public static Logger getLogger(Class clazz) { return LogManager.getLogger(clazz.getName()); } public static Logger getRootLogger() { return LogManager.getRootLogger(); } public static Logger getLogger(String name, LoggerFactory factory) { return LogManager.getLogger(name, factory); } public void trace(Object message) { if (!this.repository.isDisabled(5000)) { if (Level.TRACE.isGreaterOrEqual(this.getEffectiveLevel())) { this.forcedLog(FQCN, Level.TRACE, message, (Throwable)null); } } } // ...省略部分方法 }
其继承的 Category 类中有 debug、info 等方法。其核心方法为 log:
public void log(String callerFQCN, Priority level, Object message, Throwable t) { if(repository.isDisabled(level.level)) { return; } if(level.isGreaterOrEqual(this.getEffectiveLevel())) { forcedLog(callerFQCN, level, message, t); } }
下面再看适配器类 Log4jLoggerAdapter,它先是继承了 MarkerIgnoringBase,MarkerIgnoringBase 实现了 Logger,等于说 Log4jLoggerAdapter 实现了 Logger:
public final class Log4jLoggerAdapter extends MarkerIgnoringBase implements LocationAwareLogger, Serializable { private static final long serialVersionUID = 6182834493563598289L; final transient org.apache.log4j.Logger logger; Log4jLoggerAdapter(org.apache.log4j.Logger logger) { this.logger = logger; this.name = logger.getName(); traceCapable = isTraceCapable(); } public void debug(String msg) { logger.log(FQCN, Level.DEBUG, msg, null); } public void info(String msg) { logger.log(FQCN, Level.INFO, msg, null); } // ...省略部分方法 }
Log4jLoggerAdapter 的构造方法接收 org.apache.log4j.Logger 类型的对象,其 debug 等方法的实现中,将具体的打印工作委托给 Log4j Logger。
如果 Log4j 和 SLF4J 正常整合,则 SLF4J 的 LoggerFactory.getLogger 方法最终会返回 Log4jLoggerAdapter 的实例,从而使 Log4j 和 SLF4J 兼容。
下面是类图:
![]() |
【推荐】国内首个AI IDE,深度理解中文开发场景,立即下载体验Trae
【推荐】编程新体验,更懂你的AI,立即体验豆包MarsCode编程助手
【推荐】抖音旗下AI助手豆包,你的智能百科全书,全免费不限次数
【推荐】轻量又高性能的 SSH 工具 IShell:AI 加持,快人一步
· TypeScript + Deepseek 打造卜卦网站:技术与玄学的结合
· Manus的开源复刻OpenManus初探
· AI 智能体引爆开源社区「GitHub 热点速览」
· C#/.NET/.NET Core技术前沿周刊 | 第 29 期(2025年3.1-3.9)
· 从HTTP原因短语缺失研究HTTP/2和HTTP/3的设计差异
2022-10-26 IDEA 跳到定义或使用
2021-10-26 AutoLISP command 命令中的 _.line line -line 有什么区别