我们看到其他日志统一到slf4j的原理,我们看一下Springboot里的日志是怎么做的,首先这是springboot帮我们项目

创建的配置文件,pom文件引入了web依赖,还引入了测试依赖,而这些依赖之间的关系,到底是怎么样的呢,我们可以来分析

一下,分析有两种办法,web依赖jackson,用来做ajax的,还依赖了tomcat,嵌入式的tomcat,他还依赖了数据校验hibernate,

还用了jboss-logging,但是还依赖了springboot-starter,spring-boot-starter是每一个启动器都要依赖的东西,这是一个

最基本的依赖,而我们的spring-boot-stater我们来看一下,里面有这么几个模块,一个是自动配置,我们以前老说的自动配置

功能,在这个模块里面,stater里面依赖了自动配置,依赖了yml文件解析,snakeyml解析的,还依赖了spring-boot-starter-logging,

spring-boot里的日志是由他来做的,依赖了一个starter-logging,Springboot来用它来做日志功能,我们说每一个starter是一个

场景启动器,它是用来封装我们日志场景的,那我们这个日志是怎么用的呢,先来分析它的stater,我们这个日志记录

springboot 日志依赖 springboot jar 日志_日志记录

在我们这个starter-logging里面,依赖了这么多,而logback就是我们日志的实现,logback-core,使用logback进行日志记录,

使用logback记录日志,这是一个日志实现,然后他还导了jul-to-log4j,log4j-over-slf4j,jcl-over-slf4j,这几个是什么,

这几个就是把其他几个日志框架,他的作用就是呢,把其他日志转为slf4j的相关依赖,他就是将其他框架转成slf4j的,由于logback

都依赖slf4j,所以slf4j也导入进来,导入了日志抽象层slf4j,其实就和我们之前看slf4j官方文档一样,这是我们springboot在

底层日志依赖关系,我们springboot底层依赖关系,那用一句话总结,springboot底层也是用slf4j加logback的方式,进行日志记录,

第二个,他除了导入slf4j+logback以外,还导了jul-to-slf4j,log4j-over-slf4j,都是把什么东西变成slf4j,slf4j在后边,

把前边的日志框架变成slf4j,这就是我们在解决遗留问题的时候,我们应用要用log4j+logback,可能有其他依赖,

我们都把这个都替换成slf4j,

因为springboot也考虑到了其他日志,Springboot也把其他日志替换成了slf4j,他导了中间的替换包,中间替换包是什么东西,我们来给

大家随便看一个,比如我们就以jcl-over-slf4j为例,虽然我们的jar包叫jcl-over-slf4j,但是里面的类名,

叫org.apache.commons.logging,相当于commons-logging类都在里面,只不过这个类我们点进去看一下,

我们在用的时候比如,日志工厂

static LogFactory logFactory = new SLF4JLogFactory();

我们new的是啥,是SLF4JLogFactory,也就是他在底层偷梁换柱了一下,虽然看起来是org.apache.commons.logging下

的LogFactory,但是LogFactory在内部使用的是SLF4JLogFactory,他们就是偷梁换柱包,

这里举一个例子放到里面就行了,剩下的一样,都可以看到类似的逻辑,你都可以看到类似的逻辑,

比如你看log4j-over-slf4j,log4j转成slf4j,

org.apache.log4j

这个包名又是apache.log4j,但是真正用的时候,在Logger类里边,要进行日志记录,我们把这个点进去

/**
 * Delegates to {@link org.slf4j.Logger#trace(String)} method in SLF4J.
 */
public void trace(Object message) {
	differentiatedLog(null, LOGGER_FQCN, LocationAwareLogger.TRACE_INT, message, null);
}

void differentiatedLog(Marker marker, String fqcn, int level, Object message, Throwable t) {

	String m = convertToString(message);
	if (locationAwareLogger != null) {
		locationAwareLogger.log(marker, fqcn, level, m, null, t);
	} else {
		switch (level) {
		case LocationAwareLogger.TRACE_INT:
			slf4jLogger.trace(marker, m);
			break;
		case LocationAwareLogger.DEBUG_INT:
			slf4jLogger.debug(marker, m);
			break;
		case LocationAwareLogger.INFO_INT:
			slf4jLogger.info(marker, m);
			break;
		case LocationAwareLogger.WARN_INT:
			slf4jLogger.warn(marker, m);
			break;
		case LocationAwareLogger.ERROR_INT:
			slf4jLogger.error(marker, m);
			break;
		}
	}
}

他在日志记录的时候,他来看日志的级别,里面用的是谁的日志记录器,

protected org.slf4j.Logger slf4jLogger;

slf4j的日志记录,在日志记录的时候又是slf4j的,中间这些转换包,偷梁换柱,按你原来的方式替掉了,包名都不变一下的,

这是我们中间的转换包

springboot 日志依赖 springboot jar 日志_日志记录_02

中间转换包,他就长成这样,中间包就是这个样子,那Springboot就考虑了中间转换的问题,所以唯一

一个问题是什么,如果我们要引入其他的文件,我们在我们Springboot里面,我引入了其他框架,一定要把这个框架的

默认日志依赖移除掉,假设框架里用的是log4j,类名包名一样不就出现问题了吗,我们这个jar包就冲突了,所以我们一定

要移除掉,包括springboot也是这么做的,因为我们有一个疑问,spring框架用的是commons-logging,那spring排除了还是

没有排除commons-logging,我们可以简单来看一下,我们来到这一块,我们引入了spring-boot-logging-stater,我们以后

也就应该这么来做,我们引入新框架以后,springboot能够适配所有的日志,而且底层使用slf4j+logback记录日志,我们唯一

需要做的是,引入其他框架的时候,只需要把其他框架的日志框架,排除掉,我们不用再做任何多余的操作,直接springboot就能

适配起来,这就是springboot做日志的核心总结

springboot 日志依赖 springboot jar 日志_日志记录_03