JCL,全称为"Jakarta Commons Logging",也可称为"Apache Commons Logging"。

一、JCL原理

1、基本原理

JCL这个日志框架跟Log4J,Java Logging API等日志框架不同。JCL采用了设计模式中的“适配器模式”,它对外提供统一的接口,然后在适配类中将对日志的操作委托给具体的日志框架,比如Log4J,Java Logging API等。

在JCL中对外有两个统一的接口,分别是Log和LogFactory。

Log的继承体系如图1:

图1

LogFactory的继承体系如图2:

图2

Log4JLogger,Jdk14Logger等是适配类。

在Log4JLogger类中,包含有"org.apache.log4j.Logger"类,即Log4J中的Logger类,因而对Log4JLogger类中的日志操作方法的调用会被委托给"org.apache.log4j.Logger"类运行

在Jdk14Logger类中,包含有"java.util.logging.Logger"类,即Java Logging API中的Logger类,因而对Jdk14Logger类中的日志操作方法的调用会被委托给"java.util.logging.Logger"类运行

2、具体加载步骤

在执行以下Java代码语句的时候,经历了哪些步骤?

Log log = LogFactory.getLog(Main.class);

log.error("Hello World");

1)通过查看源代码可以发现,执行"LogFactory.getLog(Main.class)"语句的时候,最终是执行LogFactoryImp类中的discoverLogImplementation方法,在该方法中有如下代码语句:

for(int i = 0; i < classesToDiscover.length && result == null; ++i)

{

result = this.createLogFromClass(classesToDiscover[i], logCategory, true);

}

其中classesToDiscover的值如图3所示:

图3

这个过程就是依次去判断类路径中是否存在Log4J依赖,JDK依赖等。就是经常说的JCL运行时动态查找具体日志框架的过程。

2)在1)中discoverLogImplementation方法找到具体的日志框架依赖之后,会去生成相应的适配器类实例。比如找到了Log4J日志框架依赖,那么会生成一个Log4JLogger适配器类实例(以A来表示它),并将其返回。最后该适配器类实例,被赋值给"Log log = LogFactory.getLog(Main.class)"中的log对象。

3)执行log.error("Hello World");语句,实际上是执行A中的error(Object message)方法,而该方法中会去委托"A中所包含的org.apache.log4j.Logger类实例"进行处理。

二、基本原理扩展

1、本质上说,NoOpLog和SimpleLog不是适配器类,因为它们自身实现日志操作功能,而不是委托给其他日志框架。

2、关于JCL有两个包,分别是:commons-logging:commons-logging:1.1和commons-logging:commons-logging-api:1.1

这两者的主要差别在于前者比后者拥有更多的适配器类

前者中的适配器体系见图1

后者中的适配器体系见图4

图4

3、在commons-logging:commons-logging:1.1和commons-logging:commons-logging-api:1.1的pom.xml文件中,可以发现它们有对具体日志框架的依赖,比如在commons-logging:commons-logging:1.1的pom.xml中有如下片段:

log4j

log4j

1.2.12

avalon-framework

avalon-framework

4.1.3

即包含有对Log4J和avalon-framework(也是一个具体的日志框架)的依赖。其实想想也是如此,因为JCL中含有Log4JLogger,Jdk14Logger等适配器类,在这些适配器类中含有对对应的具体的日志框架的依赖,比如在Log4JLogger类中,有如下片段:

package org.apache.commons.logging.impl;

import java.io.Serializable;

import org.apache.commons.logging.Log;

import org.apache.log4j.Logger;

import org.apache.log4j.Priority;

public class Log4JLogger implements Log, Serializable {}以上这点表明,在项目中,我们只要包含了对commons-logging:commons-logging:1.1或者commons-logging:commons-logging-api:1.1的依赖,就会包含所有对它们所支持的具体日志框架的依赖。因而在JCL运行时动态查找具体日志框架的过程中,能够找到所有所支持的具体日志框架,根据具体的查找算法,选定某一个返回。

但是为了更加清晰准确,我们应该还是得在项目中包含对具体日志框架的依赖比较好,比如要使用“JCL+Log4J”的组合方案,那么在项目的pom.xml中,应该包含以下片段:

commons-logging

commons-logging

1.1

log4j

log4j

1.2.17

4、在JCL中一般情况下,需要有两个配置文件,一个是JCL自身的,另外一个是具体日志框架的。比如在JCL中,具体的日志框架使用Log4J,那么需要有"commons-logging.properties"和"log4j.properties"这两个文件

5、由上述第3点可以知道,最终使用的具体日志框架由查找算法决定,这降低了我们对日志框架使用的控制度。我们也可以通过JCL的配置文件,即"commons-logging.properties",来明确指定最终使用的具体日志框架,达到精准控制定义的目标。具体是配置文件中的"org.apache.commons.logging.Log"属性。

比如在"commons-logging.properties"文件中,配置

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

那么显式指定使用Log4J这个具体日志框架,然后也生成"org.apache.commons.logging.impl.Log4JLogger"的一个实例

三、JCL如何使用的具体例子

1、JCL+Log4J

1.1、项目中的pom.xml配置

commons-logging

commons-logging

1.1

log4j

log4j

1.2.17

1.2、commons-logging.properties和log4j.properties两个文件的内容

"commons-logging.properties"文件内容如下:

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

"log4j.properties"文件内容如下:

# Root logger option

log4j.rootLogger=INFO, stdout

# Direct log messages to stdout

log4j.appender.stdout=org.apache.log4j.ConsoleAppender

log4j.appender.stdout.Target=System.out

log4j.appender.stdout.layout=org.apache.log4j.PatternLayout

log4j.appender.stdout.layout.ConversionPattern=%d{yyyy-MM-dd HH:mm:ss} %-5p %c{1}:%L - %m%n

1.3、Java代码import org.apache.commons.logging.Log;

import org.apache.commons.logging.LogFactory;

public class Main {

public static void main(String[] args) {

Log log = LogFactory.getLog(Main.class);

log.error("Hello World");

System.out.println(log.getClass());

}

}

1.4、输出结果

如图5

图5

2、JCL+Log4J

2.1、项目中的pom.xml配置

commons-logging

commons-logging

1.1

log4j

log4j

1.2.17

2.2、commons-logging.properties和log4j.properties两个文件的内容

"commons-logging.properties"文件内容如下:

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

"log4j.properties"文件不存在

2.3、Java代码

import org.apache.commons.logging.Log;

import org.apache.commons.logging.LogFactory;

public class Main {

public static void main(String[] args) {

Log log = LogFactory.getLog(Main.class);

log.error("Hello World");

System.out.println(log.getClass());

}

}

2.4、输出结果

如图6

图6

3、JCL+Java Logging API

3.1、项目中的pom.xml配置

commons-logging

commons-logging

1.1

3.2、commons-logging.propertie和logging.properties两个文件的内容

"commons-logging.properties"文件内容如下:

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

"logging.properties"文件是Java Logging API默认的配置文件名称,默认路径是JDK_HOME/jre/lib/logging.properties

3.3、Java代码

import org.apache.commons.logging.Log;

import org.apache.commons.logging.LogFactory;

public class Main {

public static void main(String[] args) {

Log log = LogFactory.getLog(Main.class);

log.error("Hello World");

System.out.println(log.getClass());

}

}

3.4、输出结果

如图7

图7

四、其他

1、在项目中使用JCL的好处是降低与具体日志框架的耦合,可以灵活改变使用的具体日志框架

2、经典的日志框架组合为:JCL+Log4J

3、Spring项目中就选用了JCL框架

参考文献:

[1]http://commons.apache.org/proper/commons-logging/guide.html

[2]http://www.javapractices.com/topic/TopicAction.do?Id=143

java中jcl_Java日志框架——JCL相关推荐

  1. 【Log】(二)Java 中的日志框架 JCL、SLF

    [Log](一)Java 中的日志框架 JUL.Log4j [Log](二)Java 中的日志框架 JCL.SLF [Log](三)Java 中的日志框架 logback.log4j2 前言 JUL ...

  2. JAVA中的日志框架-log4j的使用

    JAVA日志-使用log4j 1. log4j.jar下载 windows下载地址: http://www.apache.org/dyn/closer.cgi/logging/log4j/1.2.15 ...

  3. Spring全家桶中的日志框架

    Spring全家桶中的日志框架 spring-jcl spring-jcl是spring的日志框架,spring-jcl底层使用的日志框架是有优先级的优先级为:LOG4J2 级是最高的,其次是SLF4 ...

  4. java中的日志处理

    java中的日志处理简介 在Java中我们可以使用自定义的.可扩展的日志处理方式.我们不仅可以使用Java中java.util.logging包提供的基本的日志相关的API来进行日志的处理,也可以使用 ...

  5. C#项目中使用日志框架Log4net

    C#项目中使用日志框架Log4net 背景 准备条件 日志服务简单封装 使用封装的服务类记录日志 配置文件App.config/Web.config 背景 无论是软件的开发期间还是发布后的运维期间,日 ...

  6. java中的集合框架_JAVA中的集合框架(上)List

    第一节 JAVA中的集合框架概述 集合的概念,现实生活中:很多事物凑在一起就是一个集合:数学中的集合:具有相同属性事物的总体:JAVA中的集合:是一种工具类,就像是容器,储存任意数量的具有共同属性的对 ...

  7. Java 中的 Swing 框架现在是不是被淘汰了?

    关于java中的Swing框架,我先说下如下的观点. 1 只要是用java开发的商业项目,就指着来挣钱的项目,都不会用Swing框架. 2 所以对java初学者来说,根本没必要学swing,甚至连类似 ...

  8. java视频马_【B0718】[java视频教程]某马2019年Java进阶课日志框架视频教程 it教程...

    Java视频教程名称:某马2019年Java进阶课日志框架视频教程      java自学网[javazx.com]  日志框架视频教程   it教程 Java自学网收集整理 java论坛' k&am ...

  9. Java中的日志级别

    昨天校招面试被问到了Java中的日志等级,当时也慌的一批,只说出了其中的三个,在这里细心为大家总结一下. java中⽇志级别有7 个级别:  severe.Warning.info.config.fi ...

最新文章

  1. MXNet中依赖库介绍及简单使用
  2. php 本地mysql 代码_基于本地数据库的 IP 地址查询 PHP 源码
  3. LeetCode27——Remove Element(移除数组中指定的元素)
  4. 软件测试—软件测试基础知识—(五)软件测试模型
  5. 随想录(常用的音视频、图像库)
  6. 使用CSDN-markdown编辑器笔记
  7. Win10家庭版安装VMware虚拟机-开启时出现蓝屏的问题
  8. VSCode创建vue模板(快捷方便)
  9. CODESYS Softmotion(一)功能介绍
  10. VSCode搭建STM32开发环境
  11. android按钮点击次数,android按键精灵 设置次数
  12. 如何守住项目管理的质量“底线”?
  13. android移动拼图小游戏的图片,利用ViewDragHelper轻松实现Android拼图游戏
  14. 有哪些比较不错的AI绘画网站?
  15. 四种基础博弈 巴什博奕+威佐夫博奕+斐波那契博弈+K倍博弈
  16. 玩游戏用什么轴的机械键盘好_机械键盘轴哪个最适合打游戏
  17. mysql枫叶_枫叶博客告诉你忘记了mysql的root密码怎么办?
  18. GeoTools读取Tiff文件
  19. 关于Web 网页设计规范
  20. 8核和16核服务器性能差异,intel再次科普:8核处理器玩游戏最好,16核真心没必要...

热门文章

  1. 实验八.方程根的MATLAB求解
  2. flex 最后一行 左对齐
  3. 全球最具影响力的大数据企业排行榜
  4. linux实现局域网IP欺骗dns域名解析
  5. SpringBoot构建电商基础秒杀项目——用户模型管理
  6. 【图分析】Centrality
  7. .NET下的图形绘制控件
  8. 动态路由原理(RIP协议+实验)
  9. 字体“XX”不支持样式“Regular”。
  10. requests.exceptions.ConnectionError: HTTPConnectionPool(host=‘localhost‘, port=8123): Max retries ex