commons-logging是apache提供的一個通用的日誌接口,是爲了不和具體的日誌方案直接耦合的一種實現。經過commons-logging用戶能夠本身選擇log4j或者jdk自帶的logging做爲具體實現。html
使用commons-logging的代碼以下java
import org.apache.commons.logging.Log;
import org.apache.commons.logging.LogFactory;
public class MyApplication {
private Log log = LogFactory.getLog(this.getClass());
}
複製代碼
Log是一個接口,LogFactory的內部回去裝載具體的日誌系統,並得到實現該Log接口的實現類,其具體流程以下apache
因此只要你引入了log4j的jar包以及對其進行了配置底層就會直接使用log4j來進行日誌輸出了,其實質就是在org.apache.commons.logging.impl.Log4JLogger(commons-logging包)的getLogger方法調用了log4j的Logger.getLogger來返回底層的Logger,當記錄日誌的時候就會經過這個Logger寫日誌。bash
slf4j全稱爲Simple Logging Facade for JAVA,java簡單日誌門面。其使用方式以下框架
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
public class MyApplication {
private Logger logger = LoggerFactory.getLogger(this.getClass());
}
複製代碼
slf4j和commons-logging不同的是,若是你沒有具體的日誌組件(logback,log4j等),它是沒法打印日誌的,若是你在一個maven項目裏面只引入slf4j的jar包,而後記錄日誌maven
public class Main {
public static Logger logger = LoggerFactory.getLogger(Main.class);
public static void main(String[] args) {
logger.info("slf4j");
System.out.println("done");
}
}
複製代碼
就會出現下面的信息this
SLF4J: Failed to load class "org.slf4j.impl.StaticLoggerBinder".
SLF4J: Defaulting to no-operation (NOP) logger implementation
SLF4J: See http://www.slf4j.org/codes.html#StaticLoggerBinder for further details.
複製代碼
若是你此時引入log4j或者logback的jar包就會打印出日誌。spa
經過LoggerFactory.getLogger()查看其實現原理,其加載Logger核心源碼以下:日誌
static Set<URL> findPossibleStaticLoggerBinderPathSet() {
Set<URL> staticLoggerBinderPathSet = new LinkedHashSet<URL>();
try {
ClassLoader loggerFactoryClassLoader = LoggerFactory.class.getClassLoader();
Enumeration<URL> paths;
if (loggerFactoryClassLoader == null) {
paths = ClassLoader.getSystemResources("org/slf4j/impl/StaticLoggerBinder.class");
} else {
paths = loggerFactoryClassLoader.getResources("org/slf4j/impl/StaticLoggerBinder.class");
}
while (paths.hasMoreElements()) {
URL path = paths.nextElement();
staticLoggerBinderPathSet.add(path);
}
} catch (IOException ioe) {
Util.report("Error getting resources from path", ioe);
}
return staticLoggerBinderPathSet;
}
複製代碼
其主要思想就是去classpath下找org/slf4j/impl/StaticLoggerBinder.class,即全部slf4j的實現,不管是log4j仍是logback都有實現類,同窗們能夠看下本身項目中的jar包。code
若是引入了多個實現,編譯器會在編譯的時候選擇其中一個實現類進行綁定,也會將具體綁定的哪一個日誌框架告訴你private static void reportActualBinding(Set<URL> binderPathSet) {
if (binderPathSet != null && binderPathSet.size() > 1) {
Util.report("Actual binding is of type [" + StaticLoggerBinder.getSingleton().getLoggerFactoryClassStr() + "]");
}
}
複製代碼