当前位置: 首页 > 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;现在都可以用二维码展示。而且现在生成音频二维码的方法也很简单&#…...

多模态2025:技术路线“神仙打架”,视频生成冲上云霄

文&#xff5c;魏琳华 编&#xff5c;王一粟 一场大会&#xff0c;聚集了中国多模态大模型的“半壁江山”。 智源大会2025为期两天的论坛中&#xff0c;汇集了学界、创业公司和大厂等三方的热门选手&#xff0c;关于多模态的集中讨论达到了前所未有的热度。其中&#xff0c;…...

Qwen3-Embedding-0.6B深度解析:多语言语义检索的轻量级利器

第一章 引言&#xff1a;语义表示的新时代挑战与Qwen3的破局之路 1.1 文本嵌入的核心价值与技术演进 在人工智能领域&#xff0c;文本嵌入技术如同连接自然语言与机器理解的“神经突触”——它将人类语言转化为计算机可计算的语义向量&#xff0c;支撑着搜索引擎、推荐系统、…...

使用van-uploader 的UI组件,结合vue2如何实现图片上传组件的封装

以下是基于 vant-ui&#xff08;适配 Vue2 版本 &#xff09;实现截图中照片上传预览、删除功能&#xff0c;并封装成可复用组件的完整代码&#xff0c;包含样式和逻辑实现&#xff0c;可直接在 Vue2 项目中使用&#xff1a; 1. 封装的图片上传组件 ImageUploader.vue <te…...

Spring Boot面试题精选汇总

&#x1f91f;致敬读者 &#x1f7e9;感谢阅读&#x1f7e6;笑口常开&#x1f7ea;生日快乐⬛早点睡觉 &#x1f4d8;博主相关 &#x1f7e7;博主信息&#x1f7e8;博客首页&#x1f7eb;专栏推荐&#x1f7e5;活动信息 文章目录 Spring Boot面试题精选汇总⚙️ **一、核心概…...

12.找到字符串中所有字母异位词

&#x1f9e0; 题目解析 题目描述&#xff1a; 给定两个字符串 s 和 p&#xff0c;找出 s 中所有 p 的字母异位词的起始索引。 返回的答案以数组形式表示。 字母异位词定义&#xff1a; 若两个字符串包含的字符种类和出现次数完全相同&#xff0c;顺序无所谓&#xff0c;则互为…...

【python异步多线程】异步多线程爬虫代码示例

claude生成的python多线程、异步代码示例&#xff0c;模拟20个网页的爬取&#xff0c;每个网页假设要0.5-2秒完成。 代码 Python多线程爬虫教程 核心概念 多线程&#xff1a;允许程序同时执行多个任务&#xff0c;提高IO密集型任务&#xff08;如网络请求&#xff09;的效率…...

AI编程--插件对比分析:CodeRider、GitHub Copilot及其他

AI编程插件对比分析&#xff1a;CodeRider、GitHub Copilot及其他 随着人工智能技术的快速发展&#xff0c;AI编程插件已成为提升开发者生产力的重要工具。CodeRider和GitHub Copilot作为市场上的领先者&#xff0c;分别以其独特的特性和生态系统吸引了大量开发者。本文将从功…...

OpenLayers 分屏对比(地图联动)

注&#xff1a;当前使用的是 ol 5.3.0 版本&#xff0c;天地图使用的key请到天地图官网申请&#xff0c;并替换为自己的key 地图分屏对比在WebGIS开发中是很常见的功能&#xff0c;和卷帘图层不一样的是&#xff0c;分屏对比是在各个地图中添加相同或者不同的图层进行对比查看。…...

Linux 中如何提取压缩文件 ?

Linux 是一种流行的开源操作系统&#xff0c;它提供了许多工具来管理、压缩和解压缩文件。压缩文件有助于节省存储空间&#xff0c;使数据传输更快。本指南将向您展示如何在 Linux 中提取不同类型的压缩文件。 1. Unpacking ZIP Files ZIP 文件是非常常见的&#xff0c;要在 …...

探索Selenium:自动化测试的神奇钥匙

目录 一、Selenium 是什么1.1 定义与概念1.2 发展历程1.3 功能概述 二、Selenium 工作原理剖析2.1 架构组成2.2 工作流程2.3 通信机制 三、Selenium 的优势3.1 跨浏览器与平台支持3.2 丰富的语言支持3.3 强大的社区支持 四、Selenium 的应用场景4.1 Web 应用自动化测试4.2 数据…...