Java日志体系

可以看到,log4j 多依赖了 log4j-slf4j-impl.jar,其实就是上图所示的适配器层,读者可能好奇,为什么使用 log4j 会有适配器层?其原因在于,slf4j 并不是官方规范,所以没人遵守(也就是自己的日志框架中没有原生实现**org.slf4j.Logger**接口,如 log4j ),而绑定层( log4j-slf4j-impl.jar)的作用就是通过静态查找的方式将使用log4j作为实现(具体原理请关注后续文章),这样就是实现了不依赖log4j而使用log4j输出日志(面向接口编程的最佳实践,Ceki 大神就是用这套思想将 slf4j 做成了 Java 日志的标准,烂牌翻盘的典范)。

上面这一段讲解了绑定(concrete-bindings)思想,是本文的精髓,读者一定要理解这里,后面还有桥接思想与之类似,请继续阅读。

小结

至此我们已经完成了日志的整合,但是事情真的这么简单吗?

先梳理一下,如此混乱的日志体系下(slf4j,jul,jcl,logback,log4j)会不会会产生什么问题?答案是一定的,各种第三方库使用了不同的日志框架,如果我们依赖 Spring ,Spring(非boot)的默认日志实现是JCL、又或者我们已有项目已经使用了Log4j,想使用logback的话,难道要逐个类改代码吗(官方有迁移工具)?我们能不能只用一种框架来处理JUL(java.util.logging)、JCL(Jakarta Commons Logging)、Log4j1、Log4j2 呢?

答案是肯定的,Ceki 的 Slf4j 给出了解决方案,就是上文所说的桥接( Bridging legacy),简单来说就是劫持以上所以第三方日志输出并重定向至 SLF4j,最终实现统一日志上层 API(编码) 与下层实现(输出日志位置、格式统一)。我们来看一下图示:

上图左侧就是前一张图的 logback 日志实现,为了兼容其他日志,我们需要引用右侧的桥接包:xxx-over/to-slf4j.jar ,xxx对应日志框架,使用 logback 的情况下,除了上文的 logback 依赖,还需要引入以下依赖才能保证所有日志都被桥接至slf4j。

如何桥接?

logback 如下


<dependency>

  <groupId>ch.qos.logback</groupId>

  <artifactId>logback-classic</artifactId>

  <version>1.2.3</version>

</dependency>

<dependency>

   <groupId>org.slf4j</groupId>

   <artifactId>jcl-over-slf4j</artifactId>

</dependency>

<dependency>

   <groupId>org.slf4j</groupId>

   <artifactId>jul-to-slf4j</artifactId>

</dependency>

<!-- log4j 桥接包,slf4j官方实现,另有log4j官方实现,二选一即可 log4j-to-slf4j-->

<dependency>

   <groupId>org.slf4j</groupId>

   <artifactId>log4j-over-slf4j</artifactId>

</dependency>复制代码

log4j2 如下


<dependency>

  <groupId>org.apache.logging.log4j</groupId>

  <artifactId>log4j-slf4j-impl</artifactId>

  <version>2.12.1</version>

</dependency>

<dependency>

  <groupId>org.apache.logging.log4j</groupId>

  <artifactId>log4j-core</artifactId>

  <version>2.12.1</version>

</dependency>

<!-- 以下是桥接包,使用了log4j作为底层实现,

     不能再桥接log4j,否则会出现无限递归的情况(具体原因请关注后续文章) -->

<dependency>

   <groupId>org.slf4j</groupId>

   <artifactId>jcl-over-slf4j</artifactId>

</dependency><dependency>

   <groupId>org.slf4j</groupId>

   <artifactId>jul-to-slf4j</artifactId>

</dependency>复制代码

SpringBoot 项目引用了一部分依赖,所以使用起来略微有些不同:

logback 如下


<!-- logback作为内置实现,使用相对简单 -->

<dependency>

    <groupId>org.springframework.boot</groupId>

    <artifactId>spring-boot-starter</artifactId>

</dependency><!-- 引入缺少的桥接包 --><dependency>

    <groupId>org.slf4j</groupId>

    <artifactId>jcl-over-slf4j</artifactId>

</dependency>复制代码

log4j2 如下


<dependency>

   <groupId>org.springframework.boot</groupId>

   <artifactId>spring-boot-starter</artifactId>

   <!-- 使用log4j2要排除logback依赖 -->

   <exclusions>

      <exclusion>

         <groupId>org.springframework.boot</groupId>

         <artifactId>spring-boot-starter-logging</artifactId>

      </exclusion>

   </exclusions>

</dependency>

<!-- Spring已经写好了一个log4j2-starter但缺少桥接包 -->

<dependency>

   <groupId>org.springframework.boot</groupId>

   <artifactId>spring-boot-starter-log4j2</artifactId>

</dependency>

<!-- 引入缺少的桥接包 -->

<dependency>

   <groupId>org.slf4j</groupId>

   <artifactId>jcl-over-slf4j</artifactId>

</dependency>复制代码

结束语

以上两种才是项目中的最佳使用方式,其他笔者不推荐使用。

最后来看一下 slf4j 如何使用:


static final org.slf4j.Logger logger = LoggerFactory.getLogger(TestLog.class);

logger.trace("A TRACE Message");

logger.debug("A DEBUG Message");

logger.info("An INFO Message");

logger.warn("A WARN Message");

logger.error("An ERROR Message");复制代码


### 最后希望可以帮助到大家!

千千万万要记得:多刷题!!多刷题!!

之前算法是我的硬伤,后面硬啃了好长一段时间才补回来,算法才是程序员的灵魂!!!!

篇幅有限,以下只能截图分享部分的资源!!

(1)多线程(这里以多线程为代表,其实整理了一本JAVA核心架构笔记集)

![image](https://img-blog.csdnimg.cn/img_convert/2721e8f0fb10eb5f96b78aafa5abee27.webp?x-oss-process=image/format,png)

(2)刷的算法题(还有左神的算法笔记)

![image](https://img-blog.csdnimg.cn/img_convert/cbf596149985436b95e5bcbedef09019.webp?x-oss-process=image/format,png)

(3)面经+真题解析+对应的相关笔记(很全面)

![image](https://img-blog.csdnimg.cn/img_convert/a2d87c90fde0da99dc24d10a7f586135.webp?x-oss-process=image/format,png)

(4)视频学习(部分)

> ps:当你觉得学不进或者累了的时候,视频是个不错的选择

在这里,最后只一句话:祝大家offer拿到手软!!

构笔记集)

[外链图片转存中...(img-UgB5m5qt-1714374650312)]

(2)刷的算法题(还有左神的算法笔记)

[外链图片转存中...(img-Nyo4hQG2-1714374650313)]

(3)面经+真题解析+对应的相关笔记(很全面)

[外链图片转存中...(img-UfMof8bY-1714374650313)]

(4)视频学习(部分)

> ps:当你觉得学不进或者累了的时候,视频是个不错的选择

在这里,最后只一句话:祝大家offer拿到手软!!

> **本文已被[CODING开源项目:【一线大厂Java面试题解析+核心总结学习笔记+最新讲解视频+实战项目源码】](https://bbs.csdn.net/topics/618154847)收录**
  • 5
    点赞
  • 10
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值