SpringBoot对日志的配置和加载进行了封装,让我们可以很方便地使用一些日志框架,只需要定义对应日志框架的配置文件,比如LogBack、Log4j、Log4j2等,代码内部便可以直接使用。
比如我们在resources目录下定义了一个logback.xml文件,文件内容是logback相关的配置,然后就可以直接在代码在使用Logger记录日志啦。
# LoggingSystem内部结构
从图中也可以发现目前SpringBoot支持4种类型的日志,分别是JDK内置的Log(JavaLoggingSystem)、Log4j(Log4JLoggingSystem)、Log4j2(Log4J2LoggingSystem)以及Logback(LogbackLoggingSystem)。
LoggingSystem是个抽象类,内部有这几个方法:
beforeInitialize方法:日志系统初始化之前需要处理的事情。抽象方法,不同的日志架构进行不同的处理
initialize方法:初始化日志系统。默认不进行任何处理,需子类进行初始化工作
cleanUp方法:日志系统的清除工作。默认不进行任何处理,需子类进行清除工作
getShutdownHandler方法:返回一个Runnable用于当jvm退出的时候处理日志系统关闭后需要进行的操作,默认返回null,也就是什么都不做
setLogLevel方法:抽象方法,用于设置对应logger的级别
AbstractLoggingSystem抽象类继承LoggingSystem抽象类,进行了一些扩展,重点在于initialize方法:
实现了beforeInitialize方法,但是内部不做任何处理
复写了initialize方法,具体过程如下
@Overridepublic void initialize(LoggingInitializationContext initializationContext, String configLocation, LogFile logFile) {
// 如果传递了日志配置文件,调用initializeWithSpecificConfig方法,使用指定的文件 if (StringUtils.hasLength(configLocation)) {
initializeWithSpecificConfig(initializationContext, configLocation, logFile); return; } // 没有传递日志配置文件的话调用initializeWithConventions方法,使用约定俗成的方式 initializeWithConventions(initializationContext, logFile);}private void initializeWithSpecificConfig( LoggingInitializationContext initializationContext, String configLocation, LogFile logFile) {
// 处理日志配置文件中的占位符 configLocation = SystemPropertyUtils.resolvePlaceholders(configLocation); loadConfiguration(initializationContext, configLocation, logFile);}private void initializeWithConventions( LoggingInitializationContext initializationContext, LogFile logFile) {
// 获取自初始化的日志配置文件,该方法会使用getStandardConfigLocations抽象方法得到的文件数组 // 然后进行遍历,如果文件存在,返回对应的文件目录。注意这里的文件指的是classpath下的文件 String config = getSelfInitializationConfig(); // 如果找到对应的日志配置文件并且logFile为null(logFile为null表示只有console会输出) if (config != null && logFile == null) {
// 调用reinitialize方法重新初始化 // 默认的reinitialize方法不做任何处理,logback,log4j和log4j2覆盖了这个方法,会进行处理 reinitialize(initializationContext); return; } // 如果没有找到对应的日志配置文件 if (config == null) {
// 调用getSpringInitializationConfig方法获取日志配置文件 // 该方法与getSelfInitializationConfig方法的区别在于getStandardConfigLocations方法得到的文件数组内部遍历的逻辑 // getSelfInitializationConfig方法直接遍历并判断classpath下是否存在对应的文件 // getSpringInitializationConfig方法遍历后判断的文件名会在后缀前加上 "-spring" 字符串 // 比如查找logback.xml文件,getSelfInitializationConfig会直接查找classpath下是否存在logback.xml文件,而getSpringInitializationConfig方法会判断classpath下是否存在logback-spring.xml文件 config = getSpringInitializationConfig(); } // 如果找到了对应的日志配置文件 if (config != null) {
// 调用loadConfiguration抽象方法,让子类实现 loadConfiguration(initializationContext, config, logFile); return; } // 还是没找到日志配置文件的话,调用loadDefaults抽象方法加载,让