1. 查找日志工厂类实例。
1.1 log = LogFactory.getLog(Class), 实际是调用getFactory().getInstance()
public static Log getLog(Class clazz)
throws LogConfigurationException {
return (getFactory().getInstance(clazz));
}
1.2 getFactory()主要查询LogFactory实现类, 查询步骤如下。
a. 查找系统环境变量:org.apache.commons.logging.LogFactory (= FACTORY_PROPERTY)
String factoryClass = getSystemProperty(FACTORY_PROPERTY, null);
b. 如果步骤a没有找到,则再次查找文件 "META-INF/services/org.apache.commons.logging.LogFactory" (=SERVICE_ID);
InputStream is = getResourceAsStream(contextClassLoader,SERVICE_ID);读取第一行
c. 如果仍然没有找到,则找配置文件"commons-logging.properties" (=FACTORY_PROPERTIES)
props = getConfigurationFile(contextClassLoader, FACTORY_PROPERTIES);
String factoryClass = props.getProperty(FACTORY_PROPERTY);
d. 如果仍然都没有,则使用默认的org.apache.commons.logging.impl.LogFactoryImpl
2 日志类查找
2.1 以默认的日志工厂类为例: org.apache.commons.logging.impl.LogFactoryImpl.getInstance(Class)
a . LogFactoryImpl.newInstance(String class.getName)
b. discoverLogImplementation(name);
c. 查找日志实现类:findUserSpecifiedLogClassName{
i) 查找commons-logging.properties的org.apache.commons.logging.Log
String specifiedClass = (String) getAttribute("org.apache.commons.logging.Log"); //
ii) 没找到,再找系统环境变量
specifiedClass = getSystemProperty(LOG_PROPERTY, null);
iii)如果找到了,根据日志实现类名实例化
result = createLogFromClass(specifiedLogClassName,
logCategory,// 日志调用的原始业务类名
true);
vi) 如果没找到,则使用默认顺序构造日志实现类,如下图顺序
private static final String[] classesToDiscover = {
“org.apache.commons.logging.impl.Log4JLogger”,
"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); // 使用默认的日志实现类
}
vii) 以org.apache.commons.logging.impl.Log4JLogger为例
constructor.newInstance({logCategory});相当于调用new Log4JLogger(logCategory)
3.日志打印(以Log4j为例):new Log4JLogger(String logCategory) // logCategory为业务逻辑类名
a.构造体 会 调用getLogger():
b.getLogger()会实例化log4j日志=org.apache.log4j.Logger.getLogger(logCategory) 实际调用Log4j的日志实现类
4.日志显示。 log.debug, 相当于调用 new Log4JLogger(String logCategory).debug(),
也就是调用 Log4j的debug方法 log4j.log(FQCN, Priority.DEBUG, message, null );
5.总结: 从上述过程可以知道LogFactory.getLog(Class)在不配置任何文件的情况下,默认使用的就是Log4j日志器.
因此在我们直接想使用Log4j的情况下,可以直接写为: org.apache.log4j.Logger.getLogger(logCategory) 即可。正如上述步骤3的演化过程结果。