java日志框架总结(四 、JCL日志门面技术)
日志框架出现的历史顺序:Log4j → JUL → JCL → slf4j → logback → log4j2
一、背景
在前面博文中,我们分别讲述了常用的2个日志框架:JUL(Java Util Logging)、Log4J。那么如何选择使用哪一个呢?
根据项目需求而定,在项目设计之初,功能比较单一简单,那么我们可以使用JUL日志框架,使用起来非常灵活,也不需要引入第三方依赖,随着我们项目升级,迭代维护,功能会越来越完善,简单的日志实现框架就不能满足我们的业务需求,那么就要进行日志升级!
如果我们从JUL日志实现框架切换为Log4j的话,代码会受到冲突影响,虽然Log4j在1.2以后,为了迎合JUL的设计思想,也把自己代码改成logger了,但它的日志级别和配置信息还是有一定的差异化,如果我们的日志代码有一万行,那么都要进行修改,这无疑是增加了很多工作量
二、JCL的诞生
为了解决这个问题,apache组织就站出来了,它就将当时比较主流的日志实现框架,例如 JUL、Log4j 将代码统一成一套API,后期软件开发阶段,只需要关联这套统一的API,就可以操作某一个日志实现框架的日志记录了,代码无需发生改变。
以面向接口的方式,来操作具体的实现。一种解耦合的思想,这个技术就是:JCL
比如web应用需要进行日志记录的话,不再直接依赖log4j、jdk14等日志实现了,而是依赖JCL这套统一的接口API,它会帮助我们调用具体的日志实现:

三、JCL 是什么?
JCL 全称为Jakarta Commons Logging,是Apache提供的一个通用日志API。
它是为 “所有的Java日志实现” 提供一个统一的接口,它自身也提供一个日志的实现,但是功能非常弱(SimpleLog)。所以一般不会单独使用它,它允许开发人员使用不同的具体日志实现工具:Log4j,JDK自带的日志(JUL)
JCL 有两个基本的抽象类:Log(基本记录器)和 LogFactory(负责创建Log实例)
快速入门案例:
引入依赖:
<dependency><groupId>commons-logging</groupId><artifactId>commons-logging</artifactId><version>1.2</version></dependency>
代码示例:
// 获取日志记录器对象Log log = LogFactory.getLog(logDemo.class.getName());// 输出日志log.info("info"); // 程序运行信息,数据库的连接、网络、IO操作等
说明:
1、首先跟log4j 和 JUL创建日志对象不同的是,JCL是用LogFactory创建的对象,创建的类型是Log不是Logger。
2、其次底层调用Log4j 或 JUL(Java util logging) ,具体调用哪个取决于引入了哪个组件,上述例子没有引入Log4j依赖,因此它底层用的是JUL日志框架。
·
如果我们引入Log4j依赖:
<dependency><groupId>log4j</groupId><artifactId>log4j</artifactId><version>1.2.13</version>
</dependency>
更改引入类型,运行代码,会提示:
会提示:找不到logger对象的appenders处理器,它希望我们设置并初始化一个系统配置信息,因为Log4j是需要初始化配置,或者引入配置文件的,所以要先加入配置文件,配置文件就不讲了,前面的log4j已经讲过,直接拷贝进来就好。
再次运行代码就可以了。
四、JCL原理
其内部主要通过LogFactory 日志工厂去加载具体的日志实现:
1. 通过LogFactory动态加载Log实现类

说明:Log类是一个接口,其实现它有4个日志框架
- SimpleLog:JCL的内置日志实现
- Log4JLogger:log4j 日志框架
- Jdk14Logger:JUL(Java Util Logging)
- Jdk13LumberjackLogger:Jdk老版本的内置日志实现
2. 日志门面支持的日志实现数组
public class LogFactoryImpl extends LogFactory {.....private static final String[] classesToDiscover = new String[]. {"org.apache.commons.logging.impl.Log4JLogger", "org.apache.commons.logging.impl.Jdk14Logger", "org.apache.commons.logging.impl.Jdk13LumberjackLogger", "org.apache.commons.logging.impl.SimpleLog"};.....}
➳ 说明:日志工厂其内部有一个加载日志的数组,加载顺序是按照数组顺序来的,这也解释了为什么入门案例中引入了Log4J,JCL内部日志框架就从JUL切换至Log4J了。
3. 具体实现代码
for(int i = 0; i < classesToDiscover.length && result == null; ++i) {
result = this.createLogFromClass(classesToDiscover[i], logCategory, true);
}
➳ 说明:通过日志数组顺序加载日志框架,如果没有找到,则继续加载下一个,否则直接返回。
✈ 源码断点查看执行流程
1. 测试类中断点debug模式进入

2. 进入到内部实现,首先初始化的是一个日志工厂 getFactory()

2. 我们暂时不关心它的实现,因此直接跳出 getFactory()

3. 继续点击进入 ,会进入到getInstance(clazz) 方法内部

4. getInstance(clazz)方法如下,其实际进行了一次封装,因此进入到内部实际初始化代码中

5. 对象初始化代码实现如下,进入点击进入到 discoverLogImplementation 方法

6. discoverLogImplementation 方法才是最终加载具体日志框架的实现,for循环加载日志数组,第一个是log4j,如果加载成功,则直接返回,否则按照顺序往下遍历加载

7. for 循环加载方法 this.createLogFromClass(),其内部实现是通过反射进行记载日志框架的

8. 由于我们增加了log4j依赖,因此直接可以拿到log4j的类名,进行反射获取到,最后直接返回

SimpleLog:JCL的内置日志实现
Log4JLogger:log4j 日志框架
Jdk14Logger:JUL(Java Util Logging)
Jdk13LumberjackLogger:Jdk老版本的内置日志实现
日志门面技术(3):JCL(Jakarta Commons Logging)_jakartacommonsloggingimpl-CSDN博客
相关文章:
java日志框架总结(四 、JCL日志门面技术)
日志框架出现的历史顺序:Log4j → JUL → JCL → slf4j → logback → log4j2 一、背景 在前面博文中,我们分别讲述了常用的2个日志框架:JUL(Java Util Logging)、Log4J。那么如何选择使用哪一个呢? 根据项…...
mfc140.dll丢失的几种修复方式,有效的解决文件丢失问题
mfc140.dll是Microsoft Foundation Class (MFC)库中的一个非常重要的DLL文件。它承载了许多被执行程序使用的函数和资源。这个库主要被广泛应用于开发Windows操作系统上的应用程序。然而,有时候我们可能会遭遇到mfc140.dll缺失或损坏的情况,这会导致依赖…...
从一个小故事讲解观察者模式~
定义对象间的一种一对多的依赖关系,当一个对象的状态发生改变时,所有依赖于它的对象都得到通知并被自动更新。 什么是观察者模式? 观察者模式在我们的日常生活中极其常见。 先来看看观察者模式的定义: 观察者模式定义了对象之间…...
LeetCode、1137. 第 N 个泰波那契数【简单,动态规划】
文章目录 前言LeetCode、1137. 第 N 个泰波那契数【简单,动态规划】题目与分类思路一维动态规划 资料获取 前言 博主介绍:✌目前全网粉丝2W,csdn博客专家、Java领域优质创作者,博客之星、阿里云平台优质作者、专注于Java后端技术…...
Python爬虫urllib详解
前言 学习爬虫,最初的操作便是模拟浏览器向服务器发出请求,那么我们需要从哪个地方做起呢?请求需要我们自己来构造吗?需要关心请求这个数据结构的实现吗?需要了解 HTTP、TCP、IP 层的网络传输通信吗?需要知…...
Linux嵌入式开发+驱动开发-中断
swi汇编指令可以产生软中断,以下是硬件中断的产生到执行完毕的全过程: 在自己设计的芯片“CPU响应中断”程序的第四个步骤可以转向“中断向量控制器”,中断向量控制器中存储中断元服务地址即处理中断处理程序的地址,而不用使用0X1…...
android tv开发-1,leanback
目录 1.leanback库的一些事 2.leanback在使用时遇到的一些麻烦 视频卡片 页面空白 关于左侧菜单的一些设置 数据加载异常与加载中的一些操作 如果页面无数据,如何显示错误的页面....
chisel RegInit/UInt/U
val reg RegInit(0.U(8.W)) //ok val reg RegInit(0.UInt(8.W)) //errU 使用在数字 . 后边50.U UInt 使用在IO(new Bundle val a Input(UInt(8.W)) 或者 def counter(max:UInt, a1:UInt) package emptyimport chisel3._ import chisel3.util._class MyCounter extends …...
华为OD机试真题-田忌赛马-2024年OD统一考试(C卷)
题目: 给定两个只包含数字的数组a,b,调整数组 a 里面数字的顺序,使得尽可能多的 a[i] >b[i]。数组 a和 b 中的数字各不相同。 输出所有可以达到最优结果的 a 数组的数量 输入描述: 输入的第一行是数组 a 中的数字,其中只包含数字,每两个数字之间相隔一个空格,a 数组…...
QMUI_Android:提升Android开发效率与质量的利器
QMUI_Android:提升Android开发效率与质量的利器 在Android应用开发过程中,开发者常常面临着重复编写基础组件和处理兼容性问题的挑战,这不仅耗费时间,也降低了开发效率。为了解决这一问题,Tencent推出了QMUI_Android框…...
如何部署Linux AMH服务器管理面板并结合内网穿透远程访问
文章目录 1. Linux 安装AMH 面板2. 本地访问AMH 面板3. Linux安装Cpolar4. 配置AMH面板公网地址5. 远程访问AMH面板6. 固定AMH面板公网地址 AMH 是一款基于 Linux 系统的服务器管理面板,它提供了一系列的功能,包括网站管理、FTP 管理、数据库管理、DNS 管…...
C++文件操作(2)
文件操作(2) 1.二进制模式读取文本文件2.使用二进制读写其他类型内容3.fstream类4.文件的随机存取文件指针的获取文件指针的移动 1.二进制模式读取文本文件 用二进制方式打开文本存储的文件时,也可以读取其中的内容,因为文本文件…...
Bootstrap5 图片轮播
Bootstrap5 轮播样式表使用的是CDN资源 <title>亚丁号</title><!-- 自定义样式表 --><link href"static/front/css/front.css" rel"stylesheet" /><!-- 新 Bootstrap5 核心 CSS 文件 --><link rel"stylesheet"…...
WINDOWS搭建NFS服务器
下载并安装 Networking Software for Windows 启动配置 找到安装目录(如C:\Program Files\nfsd),双击nfsctl.exe,菜单Edit->Preferences 启动后: 配置Export Exports->Edit exports file 其他的几句我都删除…...
LeetCode、216. 组合总和 III【中等,组合型枚举】
文章目录 前言LeetCode、216. 组合总和 III【中等,组合型枚举】题目类型与分类思路 资料获取 前言 博主介绍:✌目前全网粉丝2W,csdn博客专家、Java领域优质创作者,博客之星、阿里云平台优质作者、专注于Java后端技术领域。 涵盖…...
支持534种语言,开源大语言模型MaLA-500
无论是开源的LLaMA 2还是闭源的GPT系列模型,功能虽然很强大,但对语言的支持和扩展比较差,例如,二者都是以英语为主的大模型。 为了提升大模型语言的多元化,慕尼黑大学、赫尔辛基大学等研究人员联合开源了,…...
面试 JavaScript 框架八股文十问十答第一期
面试 JavaScript 框架八股文十问十答第一期 作者:程序员小白条,个人博客 相信看了本文后,对你的面试是有一定帮助的!关注专栏后就能收到持续更新! ⭐点赞⭐收藏⭐不迷路!⭐ 1)JavaScript有哪些…...
【发票识别】新增针对图片发票的识别(升级中)
说明 为了完善发票识别的功能,目前发票识别支持发票图片格式的识别,增加可用性。 体验 体验地址:https://invoice.behappyto.cn/invoice-service/ 体验地址上面有示例的发票,可以下载上传识别或者复制url地址进行识别。 技术栈…...
面试数据结构与算法总结分类+leetcode目录【基础版】
🧡🧡🧡算法题目总结: 这里为大家总结数据结构与算法的题库目录,如果已经解释过的题目会标注链接更新,方便查看。 数据结构概览 Array & String 大家对这两类肯定比较清楚的,同时这也是面试…...
音频二维码怎么制作出来的?支持多种格式音频生码的方法
怎么把一个音频的文件做成二维码图片呢?在日常工作和生活中,有很多的场景会需要使用音频类型的文件来展示内容,比如常见的英语听力、课程、听书等类型的内容,现在都可以用二维码展示。而且现在生成音频二维码的方法也很简单&#…...
深入理解JavaScript设计模式之单例模式
目录 什么是单例模式为什么需要单例模式常见应用场景包括 单例模式实现透明单例模式实现不透明单例模式用代理实现单例模式javaScript中的单例模式使用命名空间使用闭包封装私有变量 惰性单例通用的惰性单例 结语 什么是单例模式 单例模式(Singleton Pattern&#…...
《通信之道——从微积分到 5G》读书总结
第1章 绪 论 1.1 这是一本什么样的书 通信技术,说到底就是数学。 那些最基础、最本质的部分。 1.2 什么是通信 通信 发送方 接收方 承载信息的信号 解调出其中承载的信息 信息在发送方那里被加工成信号(调制) 把信息从信号中抽取出来&am…...
WordPress插件:AI多语言写作与智能配图、免费AI模型、SEO文章生成
厌倦手动写WordPress文章?AI自动生成,效率提升10倍! 支持多语言、自动配图、定时发布,让内容创作更轻松! AI内容生成 → 不想每天写文章?AI一键生成高质量内容!多语言支持 → 跨境电商必备&am…...
GitHub 趋势日报 (2025年06月08日)
📊 由 TrendForge 系统生成 | 🌐 https://trendforge.devlive.org/ 🌐 本日报中的项目描述已自动翻译为中文 📈 今日获星趋势图 今日获星趋势图 884 cognee 566 dify 414 HumanSystemOptimization 414 omni-tools 321 note-gen …...
C++ 求圆面积的程序(Program to find area of a circle)
给定半径r,求圆的面积。圆的面积应精确到小数点后5位。 例子: 输入:r 5 输出:78.53982 解释:由于面积 PI * r * r 3.14159265358979323846 * 5 * 5 78.53982,因为我们只保留小数点后 5 位数字。 输…...
C# SqlSugar:依赖注入与仓储模式实践
C# SqlSugar:依赖注入与仓储模式实践 在 C# 的应用开发中,数据库操作是必不可少的环节。为了让数据访问层更加简洁、高效且易于维护,许多开发者会选择成熟的 ORM(对象关系映射)框架,SqlSugar 就是其中备受…...
GC1808高性能24位立体声音频ADC芯片解析
1. 芯片概述 GC1808是一款24位立体声音频模数转换器(ADC),支持8kHz~96kHz采样率,集成Δ-Σ调制器、数字抗混叠滤波器和高通滤波器,适用于高保真音频采集场景。 2. 核心特性 高精度:24位分辨率,…...
论文阅读笔记——Muffin: Testing Deep Learning Libraries via Neural Architecture Fuzzing
Muffin 论文 现有方法 CRADLE 和 LEMON,依赖模型推理阶段输出进行差分测试,但在训练阶段是不可行的,因为训练阶段直到最后才有固定输出,中间过程是不断变化的。API 库覆盖低,因为各个 API 都是在各种具体场景下使用。…...
通过MicroSip配置自己的freeswitch服务器进行调试记录
之前用docker安装的freeswitch的,启动是正常的, 但用下面的Microsip连接不上 主要原因有可能一下几个 1、通过下面命令可以看 [rootlocalhost default]# docker exec -it freeswitch fs_cli -x "sofia status profile internal"Name …...
MySQL的pymysql操作
本章是MySQL的最后一章,MySQL到此完结,下一站Hadoop!!! 这章很简单,完整代码在最后,详细讲解之前python课程里面也有,感兴趣的可以往前找一下 一、查询操作 我们需要打开pycharm …...
