继续:使用 log4j2 API 而不是 slf4j 进行编程
它很安全:Log4j2 API 提供与 slf4j 完全相同的保证 - 甚至更多。
既然Log4j2本身被分成了API和实现模块,那么使用SLF4J就不再有任何价值了。
是的,保持您的选择余地是良好的工程实践。您稍后可能想更改为另一个日志记录实现。
在过去 10 年左右的时间里,在应用程序中构建这种灵活性意味着使用 SLF4J 等包装器 API。不过,这种灵活性并不是免费的:这种方法的缺点是您的应用程序无法使用底层日志记录库的更丰富的功能集。
Log4j2 提供的解决方案不要求您的应用程序仅限于最低公分母。
逃逸阀:log4j-to-slf4j
Log4j2 包括一个log4j-to-slf4j
桥接模块。任何针对 Log4j2 API 编码的应用程序都可以选择随时将支持实现切换到任何符合 slf4j 的实现。
![log4j-to-slf4j](https://i.stack.imgur.com/nvyhT.png)
正如问题中提到的,与使用 slf4j 等包装 API 相比,使用 Log4j2 API 直接提供更多功能,并且具有一些非功能优势:
- 消息接口
- 用于惰性日志记录的 Lambda
- 记录任何对象而不仅仅是字符串
- 无垃圾:尽可能避免创建可变参数或创建字符串
- 当您使用完项目后,CloseableThreadContext 会自动从 MDC 中删除项目
(See SLF4J 中不可用的 10 个 Log4j2 API 功能更多细节。)
应用程序可以安全地使用 Log4j2 API 的这些丰富功能,而无需锁定本机 Log4j2 核心实现。
SLF4J 仍然是您的安全阀,只是并不意味着您的应用程序应该再针对 SLF4J API 进行编码。
披露:我为 Log4j2 做出了贡献。
更新:Log4j2 API 编程以某种方式引入了“外观的外观”,这似乎有些混乱。 Log4j2 API 和 SLF4J 在这方面没有区别。
使用本机实现时,这两个 API 都需要 2 个依赖项,而使用非本机实现则需要 4 个依赖项。 SLF4J 和 Log4j2 API 在这方面是相同的。例如:
Required dependencies |
with log4j-api as API |
with SLF4J as API |
Log4j 2 as implementation |
2: log4j-api and log4j-core |
4: slf4j, log4j-slf4j-impl, log4j-api, log4j-core |
Logback as implementation |
4: log4j-api, log4j-to-slf4j, slf4j, Logback |
2: slf4j and Logback |