更新时间:2022-06-21 01:03:07
抽象类LoggingSystem指定了日志相关实例的生命周期和默认支持的日志框架。
/**
* 其支持默认支持Logback,Log4J,JavaLogging
*/
public abstract class LoggingSystem {
/**
* 返回用户指定使用的或者默认的LoggingSystem,
* 默认返回LogbackLoggingSystem
*/
public static LoggingSystem get(ClassLoader classLoader) {
String loggingSystem = System.getProperty(SYSTEM_PROPERTY);
if (StringUtils.hasLength(loggingSystem)) {
if (NONE.equals(loggingSystem)) {
return new NoOpLoggingSystem();
}
return get(classLoader, loggingSystem);
}
return SYSTEMS.entrySet().stream()
.filter((entry) -> ClassUtils.isPresent(entry.getKey(), classLoader))
.map((entry) -> get(classLoader, entry.getValue())).findFirst()
.orElseThrow(() -> new IllegalStateException(
"No suitable logging system located"));
}
}
LoggingApplicationListener来调用LoggingSystem相关生命周期方法
public class LoggingApplicationListener {
//确定了具体使用哪个日志框架,默认使用Logback
private void onApplicationStartingEvent(ApplicationStartingEvent event) {
this.loggingSystem = LoggingSystem
.get(event.getSpringApplication().getClassLoader());
this.loggingSystem.beforeInitialize();
}
//对LoggingSystem进行初始化
private void onApplicationEnvironmentPreparedEvent(
ApplicationEnvironmentPreparedEvent event) {
if (this.loggingSystem == null) {
this.loggingSystem = LoggingSystem
.get(event.getSpringApplication().getClassLoader());
}
initialize(event.getEnvironment(), event.getSpringApplication().getClassLoader());
}
//将LoggingSystem注册到容器中
private void onApplicationPreparedEvent(ApplicationPreparedEvent event) {
ConfigurableListableBeanFactory beanFactory = event.getApplicationContext()
.getBeanFactory();
if (!beanFactory.containsBean(LOGGING_SYSTEM_BEAN_NAME)) {
beanFactory.registerSingleton(LOGGING_SYSTEM_BEAN_NAME, this.loggingSystem);
}
}
//做一些清理相关的工作
private void onContextClosedEvent() {
if (this.loggingSystem != null) {
this.loggingSystem.cleanUp();
}
}
}
Springboot中使用Logback框架进行日志打印,其配置文件是如何支持springProperty标签的?
LogbackLoggingSystem在初始化的过程中会加载相关的xml配置文件,
通过logback相关的解析器进行解析,并对解析器进行来扩展(SpringBootJoranConfigurator),使其支持pringProperty标签。
SpringBootJoranConfigurator 中定义了扩展的标签和对该标签的解析方式
class SpringBootJoranConfigurator extends JoranConfigurator {
private LoggingInitializationContext initializationContext;
SpringBootJoranConfigurator(LoggingInitializationContext initializationContext) {
this.initializationContext = initializationContext;
}
@Override
public void addInstanceRules(RuleStore rs) {
super.addInstanceRules(rs);
Environment environment = this.initializationContext.getEnvironment();
rs.addRule(new ElementSelector("configuration/springProperty"),
new SpringPropertyAction(environment));
rs.addRule(new ElementSelector("*/springProfile"),
new SpringProfileAction(this.initializationContext.getEnvironment()));
rs.addRule(new ElementSelector("*/springProfile/*"), new NOPAction());
}
}