当前位置: 首页 > news >正文

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日志门面技术)

日志框架出现的历史顺序&#xff1a;Log4j → JUL → JCL → slf4j → logback → log4j2 一、背景 在前面博文中&#xff0c;我们分别讲述了常用的2个日志框架&#xff1a;JUL&#xff08;Java Util Logging&#xff09;、Log4J。那么如何选择使用哪一个呢&#xff1f; 根据项…...

mfc140.dll丢失的几种修复方式,有效的解决文件丢失问题

mfc140.dll是Microsoft Foundation Class (MFC)库中的一个非常重要的DLL文件。它承载了许多被执行程序使用的函数和资源。这个库主要被广泛应用于开发Windows操作系统上的应用程序。然而&#xff0c;有时候我们可能会遭遇到mfc140.dll缺失或损坏的情况&#xff0c;这会导致依赖…...

从一个小故事讲解观察者模式~

定义对象间的一种一对多的依赖关系&#xff0c;当一个对象的状态发生改变时&#xff0c;所有依赖于它的对象都得到通知并被自动更新。 什么是观察者模式&#xff1f; 观察者模式在我们的日常生活中极其常见。 先来看看观察者模式的定义&#xff1a; 观察者模式定义了对象之间…...

LeetCode、1137. 第 N 个泰波那契数【简单,动态规划】

文章目录 前言LeetCode、1137. 第 N 个泰波那契数【简单&#xff0c;动态规划】题目与分类思路一维动态规划 资料获取 前言 博主介绍&#xff1a;✌目前全网粉丝2W&#xff0c;csdn博客专家、Java领域优质创作者&#xff0c;博客之星、阿里云平台优质作者、专注于Java后端技术…...

Python爬虫urllib详解

前言 学习爬虫&#xff0c;最初的操作便是模拟浏览器向服务器发出请求&#xff0c;那么我们需要从哪个地方做起呢&#xff1f;请求需要我们自己来构造吗&#xff1f;需要关心请求这个数据结构的实现吗&#xff1f;需要了解 HTTP、TCP、IP 层的网络传输通信吗&#xff1f;需要知…...

Linux嵌入式开发+驱动开发-中断

swi汇编指令可以产生软中断&#xff0c;以下是硬件中断的产生到执行完毕的全过程&#xff1a; 在自己设计的芯片“CPU响应中断”程序的第四个步骤可以转向“中断向量控制器”&#xff0c;中断向量控制器中存储中断元服务地址即处理中断处理程序的地址&#xff0c;而不用使用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&#xff1a;提升Android开发效率与质量的利器 在Android应用开发过程中&#xff0c;开发者常常面临着重复编写基础组件和处理兼容性问题的挑战&#xff0c;这不仅耗费时间&#xff0c;也降低了开发效率。为了解决这一问题&#xff0c;Tencent推出了QMUI_Android框…...

如何部署Linux AMH服务器管理面板并结合内网穿透远程访问

文章目录 1. Linux 安装AMH 面板2. 本地访问AMH 面板3. Linux安装Cpolar4. 配置AMH面板公网地址5. 远程访问AMH面板6. 固定AMH面板公网地址 AMH 是一款基于 Linux 系统的服务器管理面板&#xff0c;它提供了一系列的功能&#xff0c;包括网站管理、FTP 管理、数据库管理、DNS 管…...

C++文件操作(2)

文件操作&#xff08;2&#xff09; 1.二进制模式读取文本文件2.使用二进制读写其他类型内容3.fstream类4.文件的随机存取文件指针的获取文件指针的移动 1.二进制模式读取文本文件 用二进制方式打开文本存储的文件时&#xff0c;也可以读取其中的内容&#xff0c;因为文本文件…...

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 启动配置 找到安装目录&#xff08;如C:\Program Files\nfsd&#xff09;&#xff0c;双击nfsctl.exe&#xff0c;菜单Edit->Preferences 启动后&#xff1a; 配置Export Exports->Edit exports file 其他的几句我都删除…...

LeetCode、216. 组合总和 III【中等,组合型枚举】

文章目录 前言LeetCode、216. 组合总和 III【中等&#xff0c;组合型枚举】题目类型与分类思路 资料获取 前言 博主介绍&#xff1a;✌目前全网粉丝2W&#xff0c;csdn博客专家、Java领域优质创作者&#xff0c;博客之星、阿里云平台优质作者、专注于Java后端技术领域。 涵盖…...

支持534种语言,开源大语言模型MaLA-500

无论是开源的LLaMA 2还是闭源的GPT系列模型&#xff0c;功能虽然很强大&#xff0c;但对语言的支持和扩展比较差&#xff0c;例如&#xff0c;二者都是以英语为主的大模型。 为了提升大模型语言的多元化&#xff0c;慕尼黑大学、赫尔辛基大学等研究人员联合开源了&#xff0c;…...

面试 JavaScript 框架八股文十问十答第一期

面试 JavaScript 框架八股文十问十答第一期 作者&#xff1a;程序员小白条&#xff0c;个人博客 相信看了本文后&#xff0c;对你的面试是有一定帮助的&#xff01;关注专栏后就能收到持续更新&#xff01; ⭐点赞⭐收藏⭐不迷路&#xff01;⭐ 1&#xff09;JavaScript有哪些…...

【发票识别】新增针对图片发票的识别(升级中)

说明 为了完善发票识别的功能&#xff0c;目前发票识别支持发票图片格式的识别&#xff0c;增加可用性。 体验 体验地址&#xff1a;https://invoice.behappyto.cn/invoice-service/ 体验地址上面有示例的发票&#xff0c;可以下载上传识别或者复制url地址进行识别。 技术栈…...

面试数据结构与算法总结分类+leetcode目录【基础版】

&#x1f9e1;&#x1f9e1;&#x1f9e1;算法题目总结&#xff1a; 这里为大家总结数据结构与算法的题库目录&#xff0c;如果已经解释过的题目会标注链接更新&#xff0c;方便查看。 数据结构概览 Array & String 大家对这两类肯定比较清楚的&#xff0c;同时这也是面试…...

音频二维码怎么制作出来的?支持多种格式音频生码的方法

怎么把一个音频的文件做成二维码图片呢&#xff1f;在日常工作和生活中&#xff0c;有很多的场景会需要使用音频类型的文件来展示内容&#xff0c;比如常见的英语听力、课程、听书等类型的内容&#xff0c;现在都可以用二维码展示。而且现在生成音频二维码的方法也很简单&#…...

IT行业的项目经理考不考PMP证书?我劝你看完这篇在决定!

作为在 IT 圈摸爬滚打 8 年&#xff0c;从后端开发一路转型项目经理、带过 10 大小项目的老学长&#xff0c;最近总被身边技术小伙伴追问&#xff1a;想转 PM&#xff0c;必须考 PMP 吗&#xff1f;没证书就做不好项目管理吗&#xff1f;今天就用过来人的经验&#xff0c;跟大…...

芯片缺货潮下的应对策略与国产替代方案

1. 芯片缺货潮下的行业现状最近我的一个产品项目中&#xff0c;原本采购价仅5元的ST品牌MCU&#xff08;微控制器&#xff09;价格飙升至70元&#xff0c;涨幅高达14倍。这个案例并非个例&#xff0c;而是当前全球半导体行业供应链危机的缩影。作为从业十余年的硬件工程师&…...

**跨平台开发新范式:Flutter + Dart实战构建高性能多端应用**在移动与桌面融

跨平台开发新范式&#xff1a;Flutter Dart 实战构建高性能多端应用 在移动与桌面融合加速的今天&#xff0c;跨平台开发早已不是“妥协”的代名词&#xff0c;而是开发者提升效率、降低维护成本的核心策略。本文将带你深入 Flutter Dart 的实战体系&#xff0c;通过真实项目…...

嵌入式软件框架设计:从基础到实战

1. 嵌入式软件框架设计基础作为一名在嵌入式领域摸爬滚打多年的工程师&#xff0c;我深刻体会到框架设计对项目成败的决定性影响。嵌入式系统与通用计算机系统最大的区别在于其资源受限性和实时性要求&#xff0c;这就决定了我们不能简单套用桌面开发的思维模式。程序框架本质上…...

开源工具TranslucentTB启动错误0x800401E3完整解决方案

开源工具TranslucentTB启动错误0x800401E3完整解决方案 【免费下载链接】TranslucentTB A lightweight utility that makes the Windows taskbar translucent/transparent. 项目地址: https://gitcode.com/gh_mirrors/tr/TranslucentTB TranslucentTB是一款广受欢迎的Wi…...

k8s中部署prometheus并监控k8s集群以及nginx案例

4台主机 node1主机&#xff1a;k8s集群中的master node2主机&#xff1a;搭建了harbor仓库&#xff0c;存储所需的docker镜像 test3、4主机&#xff1a;k8s集群中的woker 搭建prometheus https://github.com/prometheus-operator/kube-prometheus 获取prometheus压缩包的…...

自动药片装瓶机 No.360 三菱 组态王 基于PLC的药片装瓶自动控制系统 我们主要的后发送...

自动药片装瓶机 No.360 三菱 组态王 基于PLC的药片装瓶自动控制系统 我们主要的后发送的产品有&#xff0c;带解释的梯形图接线图原理图图纸&#xff0c;io分配&#xff0c;组态画面车间里那些药片装瓶机&#xff0c;以前人工摆瓶子、数药片&#xff0c;慢就算了&#xff0c;…...

别再混淆了!一文讲透NvDecoder里ulNumDecodeSurfaces和ulNumOutputSurfaces到底怎么用

深入解析NvDecoder&#xff1a;解码缓存与输出缓存的本质区别与实战配置 在视频处理领域&#xff0c;NVIDIA的硬件解码器&#xff08;NVDEC&#xff09;因其出色的性能和高效的资源利用率而广受开发者青睐。然而&#xff0c;对于许多中高级开发者来说&#xff0c;NvDecoder中ul…...

告别虚拟机!在Windows上用WSL2和NDK r27c交叉编译Android动态库(附CMake集成避坑指南)

在Windows上利用WSL2与NDK r27c高效构建Android动态库的完整指南 对于Android开发者而言&#xff0c;跨平台编译一直是个令人头疼的问题。传统虚拟机方案虽然功能完整&#xff0c;但资源占用高、启动慢&#xff0c;而纯Windows环境下的NDK工具链又常常遇到各种兼容性问题。本文…...

手把手教你搭建PaddleOCR开发环境:从CUDA配置到模型验证

1. 环境准备&#xff1a;从零搭建PaddleOCR开发环境 最近在做一个票据识别的项目&#xff0c;需要用到OCR技术。对比了几种开源方案后&#xff0c;发现PaddleOCR不仅识别准确率高&#xff0c;而且对中文支持特别好。但在搭建环境时踩了不少坑&#xff0c;特别是CUDA和cuDNN的版…...