一、文中会分别介绍log4j(apache),JUL(JDK自带的),JCL(apache.commons.logging),slf4j的使用方式。
1、log4j的使用
1.1 引入jar
<dependency>
<groupId>log4j</groupId>
<artifactId>log4j</artifactId>
<version>1.2.17</version>
</dependency>
1.2 添加log4j.properties配置文件
log4j.rootLogger=INFO,A1
log4j.appender.A1=org.apache.log4j.ConsoleAppender
log4j.appender.A1.target=System.out
log4j.appender.A1.layout=org.apache.log4j.PatternLayout
log4j.appender.A1.layout.ConversionPattern=%-d{yyyy-MM-dd HH:mm:ss,SSS} [%c]-[%p] %m%n
1.3 测试代码(注意导入的类路径)
import org.apache.log4j.Logger;
public class Log4j {
public static void main(String[] args) {
Logger log = Logger.getLogger(Log4j.class);
log.info("--------Log4j------");
}
}
2、JUL的使用方式(因为是JDK自带的所以不需要jar)
2.1 测试代码(注意导入的类路径)
import java.util.logging.Logger;
public class JUL {
public static void main(String[] args) {
Logger logger = Logger.getLogger("JUL");
logger.info("errr");
}
}
3、JCL(apache.commons.logging)
3.1 JCL自身是不能打印日志的,他是更具当前所能加载到的“日志类”来打印的,比如当你的项目中有log4j他就会选择log4j来打印,如果没有就会选择JUL来打印,就相当于是一个中间商。
3.2 引入jar
<dependency>
<groupId>commons-logging</groupId>
<artifactId>commons-logging</artifactId>
<version>1.2</version>
</dependency>
3.3 测试代码(注意导入的类路径)
import org.apache.commons.logging.Log;
import org.apache.commons.logging.LogFactory;
public class JCL {
public static void main(String[] args) {
Log log = LogFactory.getLog("rizhi");
log.info("jcl");
}
}
3.4 原理
通过源码我们可以知道,在创建Log对象的时候,会查询当前项目是否有如下几个类。
0 = "org.apache.commons.logging.impl.Log4JLogger"
1 = "org.apache.commons.logging.impl.Jdk14Logger"
2 = "org.apache.commons.logging.impl.Jdk13LumberjackLogger"
3 = "org.apache.commons.logging.impl.SimpleLog"
第一个就是Log4j,第二个就是JDK14,第三个就是JDK13,最后一个是默认的。也就是System.out来输出日志。如果有就通过代理(反射)来创建Log对象。完成日志输出。
4、slf4j
4.1 slf4j的原理和JCL和类似,自身是不能打印日志的,需要借助其他日志jar来输出日志,但功能上比JCL强多了,最厉害的就是他里面有桥接器,和绑定器。
4.2 引入jar
<dependency>
<groupId>org.slf4j</groupId>
<artifactId>slf4j-api</artifactId>
<version>1.7.25</version>
</dependency>
4.2 测试代码(注意导入的类路径)
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
public class slf4j {
public static void main(String[] args) {
Logger logger = LoggerFactory.getLogger(slf4j.class);
logger.info("Hello World");
}
}
输出结果
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.
提示我们无法加载org.slf4j.impl.StaticLoggerBinder,通过打印的里连接http://www.slf4j.org/codes.html#StaticLoggerBinder,在页面中我们找到这串信息
它说我们没有办法将org.slf4j.impl.StaticLoggerBinder加载到内存,This happens when no appropriate SLF4J binding could be found on the class path找不到合适的SLF4J绑定,什么意思就是说你你想要使用slf4j打印日志,你需要绑定一个日志,这个日志可以是nop,simple,log4j12,jdk14对应的jar分别是slf4j-nop.jar slf4j-simple.jar, slf4j-log4j12.jar, slf4j-jdk14.jar。按照他的提示我们在引入jar
<!--jdk14绑定器-->
<dependency>
<groupId>org.slf4j</groupId>
<artifactId>slf4j-jdk14</artifactId>
<version>1.7.25</version>
</dependency>
引入之后发现slf4j使用了JUL成功打印了日志。
当我们上面JDK14绑定器替换成log4j12绑定器
<!--jdk14绑定器-->
<!--<dependency>
<groupId>org.slf4j</groupId>
<artifactId>slf4j-jdk14</artifactId>
<version>1.7.25</version>
</dependency>-->
<!--log4j12绑定器-->
<dependency>
<groupId>org.slf4j</groupId>
<artifactId>slf4j-log4j12</artifactId>
<version>1.7.25</version>
</dependency>
引入之后发现slf4j使用了log4j成功打印了日志。因为slf4j-log4j12已经包含了log4j的jar
4.3 那么桥接器又是怎么回事呢
就比如你的项目使用了JCL来打印日志,而JCL又使用了Log4j打印日志流程就是: JCL->Log4j。如果使用JCL桥接器,就会将Log4j桥接到slf4j上面,那么流程就变成了,JCL->JCL桥接器->slf4j->xxx绑定器->xxx日志。
下面写了个Demo
先引入jar
<!--jcl-->
<dependency>
<groupId>commons-logging</groupId>
<artifactId>commons-logging</artifactId>
<version>1.2</version>
</dependency>
<!--桥接器:jcl桥接slf4j-->
<dependency>
<groupId>org.slf4j</groupId>
<artifactId>jcl-over-slf4j</artifactId>
<version>1.7.25</version>
</dependency>
<!--slf4j日志-->
<dependency>
<groupId>org.slf4j</groupId>
<artifactId>slf4j-api</artifactId>
<version>1.7.25</version>
</dependency>
<!--jdk14绑定器-->
<dependency>
<groupId>org.slf4j</groupId>
<artifactId>slf4j-jdk14</artifactId>
<version>1.7.25</version>
</dependency>
代码:
import org.apache.commons.logging.Log;
import org.apache.commons.logging.LogFactory;
public class JCL {
public static void main(String[] args) {
Log log = LogFactory.getLog(JCL.class);
log.info("jcl");
}
}
在没有引入桥接器是发现使用的JDK打印出日志的,当我们加入桥接器,从打印就变成了有slf4j到log4j。
slf4j的使用场景不单单是这些,这里我就不一一列举了。