从门面模式到 SLF4J 及其 getLogger 方法原理

基于以下内容总结:从门面模式到 Slf4j、10 分钟讲清楚 Java SLF4J,Java 日志框架的扛把子,从原理到实践

写后端接口的时候,先写一个 Service 接口,这个 Service 接口的实现中可能会调用多个其他 Service 或 Mapper 方法来实现某个业务,对于 Controller,只需要传递参数给 Service 方法就好了,这时供 Controller 调用的 Service 就是一个门面。

门面模式的主要目的是给外界提供更简单的接口。要完成一个任务,往往需要多个子系统协作,不使用门面时,客户端需要调用各子系统的多个方法,操作繁琐容易出错,使用门面时,客户端调用门面的简单接口,不用考虑太多细节,子系统交给门面调用。

门面(外观)模式也能起到统一接口的作用,当有一组完成类似功能的接口时,门面对外暴露一个统一的外形,调用方不需要知道它外形之下的具体实现是什么。很像 Java Interface 提供的作用了,但这里可能粒度更大一些,门面后面往往是一些大粒度的子系统。

简介

试想,原先我需要自己调用多个子系统各自部分或全部的功能接口以完成我的需求:

2018-08-30-15356106508820

而使用门面模式重构后,只需要调用门面提供的统一功能入口即可:

2018-08-30-15356107001587

日志框架中的应用

日志系统应该是最常见的门面模式的应用了,我们以 SLF4J 门面框架为例。

SLF4J(Simple Logging Facade for Java)和 JCL(Jakarta Commons Logging)是两个不同的日志门面系统。

介绍

SLF4J 提供了日志接口,方便程序获取具体日志对象,其自带的简单日志记录实现 slf4j-simple、自带的空实现 slf4j-nop、日志框架 Logback 等,均直接实现了 SLF4J。第三方日志框架如 reload4j、JDK 内置的日志实现 JUL 等并不直接实现 SLF4J,而是由 SLF4J 提供的适配层 slf4j-reload4j、slf4j-jdk14 来实现向 SLF4J 的适配转换。参见下图,图片来自 SLF4J 官网。

2018-08-30-concrete-bindings
翻译
2018-08-30-concrete-bindings

下面是 SLF4J 与各种底层日志框架的依赖关系:

2018-08-30-concrete-bindings

使用

获取日志对象:

private static final Logger logger = LoggerFactory.getLogger(SomeService.class);

记录日志:

logger.debug("message is {}.", message);

这里会引出一个问题,也就是LoggerFactory.getLogger(SomeService.class)是如何获取到具体的实现层实例的。

绑定实际使用的子系统

类加载机制

在 1.7 版本之前,基于类加载机制实现和实现层的绑定。

类加载时,getLogger()尝试获取 Logger 实例:

image-20200606161315662

getILoggerFactory()实例化 StaticLoggerBinder 单例,后者在不同日志框架中有不同实现:

image-20200606162010335

performInitialization()调用bind()绑定日志框架实现:

image-20200606161405254

findPossibleStaticLoggerBinderPathSet尝试在类路径中加载org/slf4j/impl/StaticLoggerBinder.class

image-20200606161405254

如果发现有多个StaticLoggerBinder.class,说明类路径下存在多个日志实现层,reportMultipleBindingAmbiguity方法会给出错误提示(但不会报错)。

image-20200606161405254

StaticLoggerBinder.getSingleton()真正完成和实现层的绑定,虚拟机将尝试加载StaticLoggerBinder这个类。没找到则会报NoClassDefFoundError异常,并被 SLF4J 捕获给出错误消息(并不会报错,SLF4J 会和自带的 NOP 实现绑定):

无任何实现
无任何实现

NOP 即 no operation,也就是不打印任何日志。

如果找到多个则 SLF4J 也不知道最终会使用哪个,只是会给出日志信息:

image-20200606162417530

所以一定要注意排查是否有多个当前日志门面的实现,若有,那么系统整体的日志打印将不可控(不论是性能还是日志位置)。

Log4j2 中的 StaticLoggerBinder:

image-20200606161601087

另:如果下载 SLF4J 的源码,会发现 StaticLoggerBinder 这个类是找不到的。这是因为在编写 SLF4J 框架时,为保证编译通过,会提供一个空实现,而在打包发布的时候,会将其移除,这样虚拟机加载到的才是具体的日志实现层:

image-20200606161601087

SPI 机制

使用类加载机制实现绑定有一些问题:

  • 对于其他框架来说,要实现一个包名为org.slf4j.impl的类;
  • 对于 SLF4J 本身来说,其 jar 包中不能有 StaticLoggerBinder 这个类,打包时需要删除。

所以后面就改为通过 SPI 机制实现了。

img
img
img

performInitialization()调用bind()方法:

img

findServiceProviders()中调用的getServiceLoader()方法:

img

getServiceLoader()方法中调用ServiceLoader.load()方法完成对SLF4JServiceProvider实现类的加载:

img

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.hqwc.cn/news/821963.html

如若内容造成侵权/违法违规/事实不符,请联系编程知识网进行投诉反馈email:809451989@qq.com,一经查实,立即删除!

相关文章

java学习10.25企业ERP生产计划管理系统(20分)

今天成功的把这个项目写好了,就是文档中的一些具体的需求比较难写(由于之前没写过) 所以项目能完成基本的增删改查和浏览操作。 使用技术栈 mybatis+thymeleft+mysql 比较复杂,写的东西比较多,以后学了springboot会更简便一些 整体架构具体页面源代码 通过百度网盘分享的文…

vscode怎么配置C语言环境

# vscode怎么配置C语言环境 在配置Visual Studio Code(VSCode)以支持C语言环境时,主要步骤包括安装C/C++扩展、配置编译器、设置调试环境。这些步骤确保了开发者可以在VSCode中高效地编写、编译和调试C语言代码。接下来,我们将详细讨论如何完成这些配置步骤。 ## 一、安装C…

Anaconda + Vscode 和 Anaconda + Pycharm安装操作教程以及问题解决

1.anaconda安装 2.打不开Anaconda Navigation 解决办法 3.如何创建虚拟环境(2种方法) 4.Anaconda+vscode 5.Anaconda+pycharm Anaconda + Vscode 和 Anaconda + Pycharm安装操作教程以及问题解决 1.anaconda安装Anaconda下载地址 我选的是2020,11的一个版本。 还没装之前电脑…

iframe有哪些加载事件

iframe的加载事件有以下几个:1、onload事件;2、onunload事件;3、onunload事件。onload事件是iframe加载完成后触发的事件。当嵌套的页面完全加载并准备好时,这个事件会被触发。开发者可以使用这个事件来执行与加载内容相关的操作,例如修改iframe的样式、内容或与其交互。一…

基于遗传算法的智能天线最佳阵列因子计算matlab仿真

1.课题概述基于遗传算法的智能天线最佳阵列因子计算。智能天线技术利用自适应阵列处理技术改善无线通信系统的性能,尤其是提高接收信号质量、抑制干扰和增强定位能力。在智能天线的设计中,阵列因子(也称加权向量或波束形成向量)的选择至关重要,它直接影响了阵列的方向性和…

网络科技和信息科技的区别是什么

​​网络科技和信息科技的区别:1.定义与侧重点不同;2.应用领域不同;3.技术内容不同;4.专业知识和技能要求不同。网络科技更多关注于数据传输、网络通信、以及基于互联网的各种服务和应用的开发,而信息科技则包括了信息的收集、处理、存储、传递、分析和使用。1.定义与侧重…

基于贝叶斯优化卷积神经网络(Bayes-CNN)的多因子数据分类识别算法matlab仿真

1.算法运行效果图预览 (完整程序运行后无水印)贝叶斯优化过程 贝叶斯优化后的CNN训练和识别结果 标准的CNN的识别结果 2.算法运行软件版本 matlab2022a3.部分核心程序 (完整版代码包含详细中文注释和操作步骤视频)% 使用贝叶斯优化算法确定最优的批次大小和学习率 [MBsize,…

.obj file format limit

.obj 文件保存的内容非常有限:顶点、纹理坐标(最多一套)、法线、三角面;它不支持顶点色、多套纹理坐标(uv2, uv3)、TANGENT、BINORMAL、骨骼权重。 搜索某度,被其内容所误导,花费不少时间 搜索.obj文件支持多套纹理坐标方式,未果!后在Blender中尝试导出带有2套纹理坐标的…

2024 CSP-J1 游记

补一篇游记罢。现在是 \(2024.10.25.22:07:10\)。 明天恰好是第二轮,hyy他们在日照已经试完机了罢。 悲。 Day-? 暑假学复赛似乎学了不少?但写的那几篇学习笔记貌似都忘干净了。。。 Day-7— 0 开学了。老师超级严,天天布置背诵任务让晚上打卡,没空卷 OI。 听说 tzyz 有 m…

2024年在线项目管理的网站哪个好?深度对比15款

深入对比15款好用的项目管理网站,包括:PingCode、Worktile、Asana、Trello、Jira、Monday.com、飞书项目、Basecamp、ClickUp、Smartsheet、Podio、Zoho Projects等。在线项目管理工具非常适合远程工作者、项目经理、中小企业、自由职业者、多项目管理人员、跨部门团队以及学…

caffe为什么要使用lmdb数据库

caffe要使用lmdb数据库的原因有:1、性能高;2、安全性好;3、空间利用率高。LMDB采用内存映射(Memory-Mapped)的方式,可以快速读取和写入大量数据。Caffe选择LMDB作为数据存储的方式,主要是因为LMDB的高性能和高空间利用率。在深度学习训练过程中,需要频繁读取和写入大量…

用人工智能,应该怎么掏钱?

人工智能(AI)服务的发展正快速改变企业和开发者的工作方式,不仅提供了强大的数据分析和预测能力,还涵盖了从自然语言处理到图像识别的广泛功能。然而,理解AI服务的支付模式对成本控制和合理资源分配至关重要,尤其是在按需扩展或实时响应的需求下。如今,AI服务领域中最常…