Apache Commons Logging 架构

作者:聂勇 欢迎转载,请保留作者信息并说明文章来源!

在以前的项目中,经常用到Apache Commons Logging,因为它可以方便地切换不同的日志框架,并且可以编写自己的日志实现类,以满足业务的需要。

一、类图 | Class Diagram

1、Commons Logging定义了一个自己的接口 org.apache.commons.logging.Log,以屏蔽不同日志框架的API差异,这里其实就是用到了Adapter Pattern(适配器模式)。
Logging类结构

上面的UML类图,只是列出了几个常用的适配器实现类,当前Commons Logging 1.1.1版本已经实现的适配器实现类有:

  • org.apache.commons.logging.impl.AvalonLogger。
  • org.apache.commons.logging.impl.Jdk13LumberjackLogger。
  • org.apache.commons.logging.impl.Jdk14Logger。
  • org.apache.commons.logging.impl.Log4JLogger。
  • org.apache.commons.logging.impl.LogKitLogger。
  • org.apache.commons.logging.impl.NoOpLog。 它很懒,什么也不做,所有给它的日志信息直接丢弃。
  • org.apache.commons.logging.impl.SimpleLog。将日志信息输出至控制台,建议只是用于开发环境,不要用于生产环境。

2、Commons Loggins 通过一个抽象工厂类 LogFactory 实现配置文件的加载解析以及实例化日志框架类。这里面就用到了两个常用的设计模式:Factory Pattern(工厂模式)、Single Pattern(单例模式)。
LogFactory类结构

同时,Commons Logging 实现了一个默认的工厂类 org.apache.commons.logging.impl.LogFactoryImpl,在未指明工厂实现类的情况下就使用它。

二、实现原理 | Realization principle

1、完整的配置文件内容:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
# 默认值true
org.apache.commons.logging.Log.allowFlawedContext=true
# 默认值true
org.apache.commons.logging.Log.allowFlawedDiscovery=true
# 默认值true
org.apache.commons.logging.Log.allowFlawedHierarchy=true
# 默认值false
use_tccl=false
# 默认值0
priority=0
configId=
# 默认值
org.apache.commons.logging.LogFactory=org.apache.commons.logging.impl.LogFactoryImpl
org.apache.commons.logging.Log=
org.apache.commons.logging.diagnostics.dest=STDERR

实际中使用的时候只需要配置 org.apache.commons.logging.Log=org.apache.commons.logging.impl.Log4JLogger,或者其他的适配器实现类以及根据项目实际需要实现的自定义适配器类。

2、使用方法:

1
private Log logger = LogFactory.getLog(Hello.class);


1
private Log logger = LogFactory.getLog("Hello");

它的执行序列图如下:

1、首先从缓存中获取工厂实现类实例,如果没有就读取配置文件中的配置项 org.apache.commons.logging.LogFactory 获取工厂实现类并进行实例化,如果没有配置或者找不到对应的类,就使用默认的工厂类 org.apache.commons.logging.impl.LogFactoryImpl 进行初始化并放入缓存。
2、根据”name“从缓存中获取日志适配器实现类实例,如果没有就新生成一个并放入缓存。

参考资料 | References

1、Apache Commons Logging User Guide