日志门面介绍和JCL使用

日志门面概述

之前有写过Java日志框架JUL和Log4j介绍,可以对比发现它们之间的使用还是有一些区别的,比如有一些类名是不同的、日志的输出级别也不完全一致。

那么实际上是增大了日志框架与程序的耦合性,使得难以更换日志框架。
甚至会造成一些优秀的框架强制性依赖某一个具体的日志实现类,为了解决这个问题,日志门面技术就诞生了。

日志门面实质上就是提供了一套通用的日志API技术,和JDBC的思想类似,使用日志门面,就可以轻松地更换日志实现。

我们为什么要使用日志门面:
1. 面向接口开发,不再依赖具体的实现类减少代码的耦合
2. 项目通过导入不同的日志实现类,可以灵活的切换日志框架
3. 统一API,方便开发者学习和使用
4. 统一配置便于项目日志的管理

常见的日志门面:JCL、slf4j

JCL

JCL介绍

JCL全称为Jakarta Commons Logging,是 Apache提供的一个通用日志API

它是为“所有的Java日志实现”提供一个统一的接口,它自身也提供一个日志的实现,但是功能非常常弱
(SimpleLog)。所以一般不会单独使用它。他允许开发人员使用不同的具体日志实现工具:Log4j、jdk自带的日志(JUL)。

JCL使用

maven依赖:

<dependency>
    <groupId>commons-logging</groupId>
    <artifactId>commons-logging</artifactId>
    <version>1.2</version>
</dependency>

如果要使用log4j还需加上log4j的依赖

核心类:

  • Log:日志记录器,用于写日志
  • LogFactory:日志记录器的工厂类,用于获取日志记录器。

JCL的日志级别:

  • trace
  • debug
  • info
  • warn
  • error
  • fatal

可以看出和log4j的日志级别一致,但它把JUL的日志级别也适配到了这套日志级别上。

对于配置文件,如果使用JUL就添加JUL的配置文件,如果使用log4j就添加Log4j的配置文件。

JCL默认会根据如下顺序查找日志的实现类:

private static final String[] classesToDiscover = {
        LOGGING_IMPL_LOG4J_LOGGER,
        "org.apache.commons.logging.impl.Jdk14Logger",
        "org.apache.commons.logging.impl.Jdk13LumberjackLogger",
        "org.apache.commons.logging.impl.SimpleLog"
};

for(int i=0; i<classesToDiscover.length && result == null; ++i) {
    result = createLogFromClass(classesToDiscover[i], logCategory, true);
}

其中LOGGING_IMPL_LOG4J_LOGGER代表的是log4j的org.apache.commons.logging.impl.Log4JLogger,可以看到JCL支持的日志实现有:

  • log4j
  • jdk1.4的日志(JUL)
  • jdk1.3前的LumberjackLogger(已经淘汰)
  • JCL自带的SimpleLog

如果用户不指定使用哪个日志实现类,JCL会按这个顺序查找,使用最先找到的实现类。

如果需要指定,还需要添加一个配置文件commons-logging.properties在类路径下:

org.apache.commons.logging.Log=org.apache.commons.logging.impl.SimpleLog

此后就可以使用了:

Log log = LogFactory.getLog(JCLTest.class);
log.info("hello JCL");

JCL的问题

JCL的问题是,当初设计的时候只考虑到了在当时比较主流的日志框架log4j、JUL,也只支持这几个日志框架,导致后面如果出现了更强大的日志框架,比如说logback出现后,如果需要使用logback,JCL需要通过修改代码的方式来适配,当然这会造成很大的麻烦。

JCL获取日志工厂的过程中使用了classLoader来寻找日志工厂实现,进而导致了其他组件,如若使用自己的classloader,则不能获取具体的日志工厂对象,则导致启动失败。(即无法动态查找)

于是不久commons-logging就退出了人们的视线,更好的日志门面技术slf4j诞生以取代它的位置。

原创文章,作者:彭晨涛,如若转载,请注明出处:https://www.codetool.top/article/%e6%97%a5%e5%bf%97%e9%97%a8%e9%9d%a2%e4%bb%8b%e7%bb%8d%e5%92%8cjcl%e4%bd%bf%e7%94%a8/

(0)
彭晨涛彭晨涛管理者
上一篇 2020年3月9日
下一篇 2020年3月9日

相关推荐

  • Java基础查缺补漏02

    哈哈我其实没有想到这个系列真会有续集,上次写完01以后以为不会再写下去了,没想到最近牛客网刷题有些题目还是挺纠结的,这里补一补 构造器能带哪些修饰符 题目: Which of th…

    Java 2020年5月25日
    080
  • Java基础查缺补漏01

    某些点会在不远的将来深挖。 >>是逻辑右移,>>>是算术右移 JDK6 可以使用Console.readPassword从控制台中读取密码,用户输入的过程中密码是不可见的。…

    2019年11月26日
    0590
  • JUC包下的读写锁ReentrantReadWriteLock以及StampedLock

    ReentrantReadWriteLock 概述 当读操作远远高于写操作时,这时候使用 读写锁 让 读-读 可以并发,提高性能。 类似于数据库中的 select ... from…

    2020年2月5日
    0140
  • AQS及其应用ReentrantLock源码分析

    AQS原理 概述 全称是 AbstractQueuedSynchronizer(抽象同步队列),是阻塞式锁和相关的同步器工具的框架。 特点:+ 用 state 属性来表示资源的状态…

    2020年2月4日
    0120
  • 深入理解java虚拟机第三版读书笔记05

    续深入理解java虚拟机第三版读书笔记04 HotSpot的算法细节实现 根节点枚举 如何高效的找出所有GC Roots? 迄今为止,所有收集器在根节点枚举这一步骤时都是必须暂停用…

    2020年1月12日
    0580
  • 深入理解java虚拟机第三版读书笔记03

    续深入理解java虚拟机第三版读书笔记02 HotSpot虚拟机对象探秘 对象的创建 当Java虚拟机遇到一条字节码new指令时,首先将去检查这个指令的参数是否能在常量池中定位到一…

    2020年1月6日
    0140
  • ThreadLocal源码分析和相关理解

    总结 总结放前面防止太长不看: 每个线程都有一个threadLocals字段,是一个ThreadLocalMap的实例,所有的ThreadLocal代表的线程私有数据都存放在这里面…

    Java 2020年2月13日
    0210
  • ArrayList源码分析

    总结 总结放前面防止太长不看: ArrayList内部是用数组实现的。 如果使用无参构造函数建立ArrayList,在添加第一个元素的时候会分配10个元素的空间。 ArrayLis…

    2019年11月22日
    0160
  • Java之UDP编程

    DatagramSocket概述 上次在Java网络套接字Socket编程那篇博客里只写了Socket和ServerSocket,即TCP通信,这次来补充一下UDP通信。 和Soc…

    Java 2020年3月11日
    0810
  • Java中的四种内部类

    我发现最近真是越来越没有东西写了。。。不可能天天学习新知识啊,最近在复习阶段了,复习的东西大多数是博客里写过的/(ㄒoㄒ)/ 复习Java基础的时候认真看了一下Java的内部类,这…

    Java 2020年5月23日
    0100

发表回复

登录后才能评论