slf4j log4j log4j-over-slf4j self-log4j12

news2024/11/23 21:08:39

一、Java日志体系概述

在这里插入图片描述
图1-1 Java日志体系概况

  1. 日志门面接口(SLF4J、JCL)
  2. 一系列绑定和桥接
  3. 具体的日志实现

先来两个例子:

Spring项目中通过Commons Logging直接使用log4j

通过Commons Logging使用log4j

图1-2 通过Commons Logging使用log4j

本例中由于spring-core中原生依赖commons-logging,所以只需要添加log4j和log4j的配置文件就能work(当然引入其它依赖还会有解冲突的工作要做)。

Spring项目中通过SLF4J使用log4j

在这里插入图片描述

图1-3 Spring中通过SLF4J使用log4j

此例中比之前多引入了3个jar包并且还排除了commons-logging依赖。如果对此有疑问,请看后面的详细解说。

spring-boot项目 中使用SLF4J

<dependency>        
	<groupId>org.springframework.boot</groupId>            
	<artifactId>spring‐boot‐starter</artifactId>            
</dependency> 

spring‐boot‐starter中找到spring‐boot‐starter‐logging依赖

<dependency>    
	<groupId>org.springframework.boot</groupId>            
	<artifactId>spring‐boot‐starter‐logging</artifactId>            
</dependency>

在这里插入图片描述

log4j有大致两个版本 log4j和 log4j2

log4j-to-slf4j.jar 和 log4j-over-slf4j.jar 之间的区别?

根据我在网上看到的内容 前者是 log4j2 桥接到slf4j; 后者是 log4j 桥接到slf4j;

slf4j-log4j12又是什么东西呢? 难道log4j还有一个12版本???

并不是的,slf4j-log4j12.jar名字中的log4j指的是log4j,12应该是与log4j的终版1.2版本有关系(本人猜测)

log4j2与slf4j绑定(整合)

<dependency>
	<groupId>org.apache.logging.log4j</groupId>
	<artifactId>log4j-api</artifactId>
	<version>2.2</version>
</dependency>
<dependency>
	<groupId>org.apache.logging.log4j</groupId>
	<artifactId>log4j-core</artifactId>
	<version>2.2</version>
</dependency>
 
<dependency>
	<groupId>org.apache.logging.log4j</groupId>
	<artifactId>log4j-slf4j-impl</artifactId>
	<version>2.1</version>
</dependency>
 
<dependency>
	<groupId>org.slf4j</groupId>
	<artifactId>slf4j-api</artifactId>
	<version>1.7.7</version>
</dependency>

二、为什么要使用SLF4J

在这里插入图片描述

图2-1 列举几点简单的原因

三、SLF4J的最佳实践

现在越来越多项目使用SLF4J (为什么要使用SLF4j)作为一个日志门面,而不是使用古老的Commons Logging。这给复杂的Maven构建带来了新的挑战,因为SLF4J仅当依赖被正确配置时才能正常工作。为了搞清楚为什么如此,让我们来看看组成SLF4J中不同的组件。

  • slf4j-api 包含了SLF4J API,比如,使用SLF4J的一个应用或者库直接依赖的所有classes。
  • 一系列绑定,它们(slf4j-log4j12,slf4j-jdk14和slf4j-jcl)基于一个已存在的日志框架来实现了SLF4J API,或者为SLF4J开发原生实现(slf4j-nop和slf4j-simple)。
    绑定的原理是因为slf4j-api中的LogFactory通过StaticLoggerBinder.getSingleton()获取具体实现logger,一个绑定包实现了org/slf4j/impl/StaticLoggerBinder.class,所以它们在编译时刻就绑定在一起,而绑定包中的StaticLoggerBinder类会绑定对应的实现。这部分看看源码就一目了然了。
  • 一系列桥接,它们把已存在的日志门面适配到SLF4J(jul-to-slf4j)。或者仿效已存在的日志门面或者实现(jcl-over-slf4j和log4j-over-slf4j)。
    桥接的原理是把对应的门面日志接口重新实现了一遍,包名、类名、接口都一样,只是具体实现它委托给SLF4J了。

SLF4J要在一个Maven构建的项目中正确工作,下列条件必须满足:

  1. 项目必须依赖slf4j-api。如果项目本身使用SLF4J,而且并不依赖任何绑定或者桥接,那么这应该是一个直接依赖。如果SLF4J被项目中的一个或者多个依赖使用,但是并不被项目本身使用,那么可以优先让Maven的依赖管理(dependency management)系统把它作为一个传递依赖给包含进来。
  2. 如果一个项目生成一个可执行的构建(有Main-Class的JAR,WAR,EAR或者二进制distribution),那么它必须有一个依赖,并且和仅一个绑定。一个binding在运行时总是必须的,但是多个bindings将会导致不可预期的行为。
  3. 项目可以有任意个SLF4J桥接依赖,这不包括被binding使用的API的桥接。比如,如果slf4j-log4j12被作为一个binding,那么项目不能依赖log4j-over-slf4j。否则应用可能因为无限循环而崩溃。
  4. 如果项目依赖一个桥接,emulate一个已存在的日志API,那么它一定不能同时依赖你这个API。比如,如果jcl-over-slf4j被使用,那么项目一定不能依赖commons-logging。否则行为将不可预测。
  5. 依赖不能混用SLF4J 1.4.x的构建和1.5.x的构建,因为它们相互不兼容。
    应当注意规则2仅适用可执行构建。一个生成一个库构建的项目不应该依赖任何SLF4J binding,除了在test scope。原因是在编译或者运行scope依赖一个指定的SLF4J binding将会在下游项目中impose一个特殊的日志实现。在每个库都遵循这个实践的完美世界里,将会非常容易地验证以上5个条件:在从SLF4J 1.5.x到每一个生成可执行构建的Maven项目中,期望的binding(任何必要的桥接)上简单添加一个依赖就足够了。
    但是世界并不完美,并且有很多第三方库并没有依赖特定的SLF4J bindings和日志实现。如果一个项目开始依赖这种库的依赖,如果没有采取对策,事情很容易失控。对于有很多依赖的项目这尤其明显,它几乎总会让以上5条规则不再被满足。

Maven并没有一些必要的特性,这些特性强制这些条件实现校验,并且强制它们具备一些准则和人工干预。另一方面,当系统地应用时有一个非常简单和高效的策略:

  • 确保在你控制下的项目中,总是遵循上诉描述的策略。
  • 对于不遵循这些最佳实践的第三方库,在对应的依赖声明上排除依赖来移除对SLF4J binding上的传递依赖。需要注意,如果在一个库在多模块Maven项目的多种模块中被使用,那么在父POM中的dependency management section里声明这些排除会很方便,这就不需要再依赖中重复排除。

四、SLF4J官方说明

  1. SLF4J与每种具体日志框架的绑定规则。
    在这里插入图片描述

    图3-1 slf4j官方逻辑图

  2. 把Commons logging,log4j和java.util.logging桥接到SLF4J,底层使用logback的case。
    在这里插入图片描述

    图3-2 桥接到SLF4J,并使用logback日志框架

  3. 把commons-logging和java.util.logging桥接到SLF4J,底层用log4j
    在这里插入图片描述

    图3-3 桥接到SLF4J,底层用log4j

  4. 把commons-logging和log4j桥接到SLF4J,底层用java.util.logging
    在这里插入图片描述

    图3-4 桥接到SLF4J,底层用java.util.logging

总结:
在Spring中,我们通常会依赖很多jar,它们使用不同的日志门面接口或者不同的日志框架,只要遵循第三节中的5点规则,加上排除冲突的依赖就能正常使用日志啦。

附录,推荐排除冲突的两种方式:

  1. 如果有多个子模块依赖相同的包,那么放在 中来管理:

    <dependencyManagement>
        <dependency>
            <groupid>com.acme</groupid>
            <artifactid>java-coffee-machine</artifactid>
            <version>7.5.194.3</version>
            <exclusions>
                <exclusion>
                    <groupid>org.slf4j</groupid>
                    <artifactid>slf4j-log4j12</artifactid>
                </exclusion>
            </exclusions>
        </dependency>
    </dependencyManagement>
    
  2. 在自己公司的maven仓库中放一个空包,scope=provided,这样可以全局排除依赖:

    <dependency>
        <groupId>commons-logging</groupId>
        <artifactId>commons-logging</artifactId>
        <version>${empty.version}</version>
        <scope>provided</scope>
    </dependency>
    

比如我们项目中依赖了spring-core,因为它原生依赖commons-logging,所以需要用jcl-over-slf4j.jar桥接包来代替commons-logging把具体实现委托给slf4j。jcl-over-slf4j和commons-logging拥有相同的包名、类名、接口,所以项目中要排除掉commons-logging。

参考资料:

  • 复杂Maven项目中管理SLF4J依赖
  • java日志工具之SLF4J
  • slf4J官网
  • slf4j在maven仓库中的相关包
  • How to use log4j 2.0 and slf4j and Commons Logging together
  • log4j-over-slf4j与slf4j-log4j12共存stack overflow异常分析

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

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈,一经查实,立即删除!

相关文章

IS200TREGH1BEC直流并励电动机的启动

​ IS200TREGH1BEC​​​​​​直流并励电动机的启动 要启动机器&#xff0c;电机在零速时产生的扭矩必须超过负载所需的扭矩。然后 TM − TL 将为正&#xff0c;d!/dt 也为正&#xff0c;机器加速。 通常&#xff0c;直流电机的电枢电阻在满载电流时会导致 1% 到 5% 的下降。…

制作RPM包createrepo

每次源码安装很费事&#xff0c;所以直接做一个RPM包 安装 rpm-build 软件包 [rootproxy ~]# yum -y install rpm-build 生成 rpmbuild 目录结构 或许只有在家目录下生成一个不存在的目录才会生成 rpmbuild目录和子目录 若想在自己创建的目录下生成只有自己手动去创建&#…

基于.NET实现的家电维修保养信息系统[含文档+PPT+源码等]精品

1 项目简介 Hi&#xff0c;各位同学好呀&#xff0c;这里是卡莫&#xff01; 基于.NET实现的家电维修保养信息系统[含文档PPT源码等]精品 该项目含有源码、文档、PPT、配套开发软件、软件安装教程、项目发布教程等 软件开发环境及开发工具&#xff1a; 开发软件&#xff1a;…

怎么查看特定的端口是否被屏蔽了

文章目录 怎么查看特定的端口是否被屏蔽了前言无法访问原因查看命令所用环境开启windows的telnet功能查看特定端口是否被墙WSL演示windows终端演示总结 怎么查看特定的端口是否被屏蔽了 前言 如果你不知道自己的服务器的某个端口是否被屏蔽了&#xff0c;通过阅读本文&#x…

如何利用EAP系统优化锂电生产线的自动化流程?

锂电行业是新兴的能源产业&#xff0c;其快速发展和规模化生产对设备自动化系统的需求也越来越高。在生产过程中&#xff0c;设备自动化系统EAP&#xff08;Equipment Automation Program&#xff09;可以实现对生产线上的所有机台进行实时管控&#xff0c;从而实现设备运行的自…

“AIGC早报”已内测2个月了,来看看她长什么样子

今天&#xff0c;是咱们社群“AI产品经理大本营”六周年活动的第二天&#xff0c;正式给大家介绍下&#xff0c;已内测2个月的重要会员权益——AIGC日报。 会分三个部分&#xff1a;效果口碑、我们如何做到的、今日的AIGC早报展示‍‍‍‍‍‍‍‍ ps&#xff0c;文末会发福利星…

将群晖NAS加入域控,来点企业级应用

1. 使用逻辑 将NAS加入域&#xff0c;所有套件和文件可通过域用户来访问。设置NAS中的文件夹权限时&#xff0c;NAS识别出域用户和域群组&#xff0c;并可设置二级文件夹的权限。域管理员会成为NAS的管理员。在域控管理台&#xff0c;可以看到NAS加入到了域控中&#xff0c;在…

dom操作

<script>var htmlEldocument.documentElementvar bodyEldocument.bodyvar headEldocument.headvar doctypedocument.doctypeconsole.log(htmlEl,bodyEl,headEl,doctype)</script> ul>li{$}*5 节点之间的关系(极少用) 空行注释没标签包括的文字也算是一个节点 子…

快速排序加量改进_CUTOFF+三点中值法+三路划分

目录 1引入情境2 形式化描述2-1递归结构2-2 一次划分2-3 C实现 3 在工程中的改进3-1 处理重复元素双向划分三路划分C 实现 3-2 最差情况的改进三点中值法随机选择pivot短序列切回插入排序 4 全部改进技术加持 1引入情境 从低到高排成一队&#xff0c;怎么办&#xff1f; 以大雄…

通过gulp+vite搭建vue3组件库

核心要点 通过 vite 搭建运行环境通过 gulp 执行编译流程通过 vite 编译组件代码编写 组件测试 组件打包 编译组件上传 npm 1、通过 vite 搭建运行环境 这里主要是创建一个可以运行的测试的组件的环境&#xff0c;全局安装vite脚手架&#xff0c;并初始化项目 npm create v…

简单两步创建nVisual建筑场景

nVisual是一款网络基础设施可视化管理软件&#xff0c;通过模型可规划即将建设的机房效果&#xff0c;或者将已有的机房场景复刻至系统中&#xff0c;便于运维管理者清晰的了解机房设备及线缆路由连接关系。 数据初始我们需要将数据中心场景复刻至系统中&#xff0c;建筑场景也…

meta标签复习总结

文章目录 前言一、用在哪里二、用途1.charset2.http-equiv3.name4.content5.keywords 前言 我们往往忽视&#xff0c;却又很重要的一个标签&#xff0c;meta&#xff0c;它在页面细节上面还提供了不小的作用。 一、用在哪里 先来看看它用法 <!DOCTYPE html> <html …

union和位域的混合使用

1、union&#xff08;共用体&#xff09; 1.1、概述 C 语言中&#xff0c;union是一种数据类型&#xff0c;对比于结构体&#xff0c;结构体中的每个成员都占用独立的内存空间&#xff0c;而联合中所有的成员都共享同一个内存空间。 也就是说&#xff0c;union中的不同成员要…

Android WebRTC+SRS/ZLM视频通话(5):Android使用WebRTC从SRS/ZLMediaKit拉流

Android WebRTCSRS/ZLM视频通话&#xff08;5&#xff09;&#xff1a;Android使用WebRTC从SRS/ZLMediaKit拉流 来自奔三人员的焦虑日志 接着上一章内容&#xff0c;继续来记录Android是如何使用WebRTC从SRS/ZLMediaKit拉流播放。WebRTC是一种实现实时音视频通信的技术&#xf…

三分钟教你如何定义自己的ChatGPT

三分钟教你如何定义自己的ChatGPT 成品预览材料准备MyChatGPT自定义AI 成品预览 材料准备 总共有两种方式&#xff1a; 一种是使用自己的OpenAI账号&#xff0c;这种方式是可控性比较强&#xff0c;同时也会有很多问题&#xff0c;比如你需要准备国外的手机号和Visa卡&#x…

目标检测论文总结

文章目录 1.目标检测论文123456789101112131415161718192021**22****25**2627 总结改进思路 1.目标检测论文 EI https://www.engineeringvillage.com/search/quick.url 其他 A YOLOv3-based Deep Learning Application Research for Condition Monitoring of Rail Thermite …

极客公园对话 Zilliz 星爵:大模型时代,需要新的「存储基建」

大模型在以「日更」进展的同时&#xff0c;不知不觉也带来一股焦虑情绪&#xff1a;估值 130 亿美元的 AI 写作工具 Grammarly 在 ChatGPT 发布后网站用户直线下降&#xff1b;AI 聊天机器人独角兽公司 Character.AI 的自建大模型在 ChatGPT 进步之下&#xff0c;被质疑能否形成…

外观、装饰、策略模式代码详解-软件设计(七十二)

真题详解&#xff08;索引长度计算&#xff09;-软件设计&#xff08;七十一)https://blog.csdn.net/ke1ying/article/details/130590260 外观模式 解析&#xff1a; public String getName()public void dispose(Patient patient)new ConcreteOatient(“name”)Facadenew Fa…

UPF问题解决

UPF配置文件内容解析 NWI Network Instance of the interface 结果调查&#xff0c;对upf网元配置文件进行了如下修改 将 - IF_2_NWIaccess.oai.org改为 - IF_2_NWIaccess3.oai.org 将 - IF_2_NWIaccess.oai.org改为 - IF_2_NWIaccess3.oai.org 然后两核心网接入了两个基站启…

Apache Doris 2.0 冷热分离快速体验

概述 对于任何一种数据库类软件来说&#xff0c;无论其基于传统数据库模型还是基于分布式结构&#xff0c;作为核心的永远是数据本身。而数据的生命周期&#xff0c;则体现在CRUD操作&#xff08;创建、查询、更新、删除&#xff09;上。任何一条数据从其生成的时刻开始&#…