怎么在springboot中设置默认日志框架

今天就跟大家聊聊有关怎么在springboot中设置默认日志框架,可能很多人都不太了解,为了让大家更加了解,小编给大家总结了以下内容,希望大家根据这篇文章可以有所收获。

环境配置:macbook; intellij idea community edition 2020.03 ; gradle 6.8.3 jdk1.8 ;

怎么在springboot中设置默认日志框架

gradle引用包如下:

dependencies{
compile"com.alibaba:fastjson:1.2.75"
compile"mysql:mysql-connector-java"

//spring
compile("org.springframework.boot:spring-boot-starter")
compile("org.mybatis.spring.boot:mybatis-spring-boot-starter:2.1.4")
compile("org.springframework.boot:spring-boot-starter-web")
compile("org.springframework.boot:spring-boot-starter-actuator")

//lombok
compileOnly'org.projectlombok:lombok'
annotationProcessor'org.projectlombok:lombok'

//test
testCompile('org.springframework.boot:spring-boot-starter-test')
testImplementation'io.projectreactor:reactor-test'
}

springboot 默认日志使用的是logback(引入spring-boot-starter包后,就自动引入了logback-core,logback-classic两个包,当然还有slf4j的包),当springboot启动时,org.springframework.boot.context.logging.LoggingApplicationListener,该类211行注册的监控事件会被ApplicationStartingEvent触发;如下代码所示,会调用onApplicationStartingEvent初始化loggingSystem,而使用哪个日志组件,就要看loggingSystem初始化的值了

@Override
publicvoidonApplicationEvent(ApplicationEventevent){
if(eventinstanceofApplicationStartingEvent){
onApplicationStartingEvent((ApplicationStartingEvent)event);
}
elseif(eventinstanceofApplicationEnvironmentPreparedEvent){
onApplicationEnvironmentPreparedEvent((ApplicationEnvironmentPreparedEvent)event);
}
elseif(eventinstanceofApplicationPreparedEvent){
onApplicationPreparedEvent((ApplicationPreparedEvent)event);
}
elseif(eventinstanceofContextClosedEvent
&&((ContextClosedEvent)event).getApplicationContext().getParent()==null){
onContextClosedEvent();
}
elseif(eventinstanceofApplicationFailedEvent){
onApplicationFailedEvent();
}
}

privatevoidonApplicationStartingEvent(ApplicationStartingEventevent){
this.loggingSystem=LoggingSystem.get(event.getSpringApplication().getClassLoader());
this.loggingSystem.beforeInitialize();
}

如下图是org.springframework.boot.logging.LoggingSystem类里面get函数的内容:首先会从system.getProperty中获取className,新生成的项目,取到的这个值都为空,SYSTEM_PROPERTY是一个固定值,就是该类的名字;那么loggingSystem的值就是从SYSTEM_FACTORY.getLoggingSystem(classLoader);获取到的;接下来我们得看LoggingSystemFactory.fromSpringFactories.getLoggingSystem取的值是什么了;

publicstaticfinalStringSYSTEM_PROPERTY=LoggingSystem.class.getName();
privatestaticfinalLoggingSystemFactorySYSTEM_FACTORY=LoggingSystemFactory.fromSpringFactories();
publicstaticLoggingSystemget(ClassLoaderclassLoader){
StringloggingSystemClassName=System.getProperty(SYSTEM_PROPERTY);
if(StringUtils.hasLength(loggingSystemClassName)){
if(NONE.equals(loggingSystemClassName)){
returnnewNoOpLoggingSystem();
}
returnget(classLoader,loggingSystemClassName);
}
LoggingSystemloggingSystem=SYSTEM_FACTORY.getLoggingSystem(classLoader);
Assert.state(loggingSystem!=null,"Nosuitableloggingsystemlocated");
returnloggingSystem;
}

privatestaticLoggingSystemget(ClassLoaderclassLoader,StringloggingSystemClassName){
try{
Class<?>systemClass=ClassUtils.forName(loggingSystemClassName,classLoader);
Constructor<?>constructor=systemClass.getDeclaredConstructor(ClassLoader.class);
constructor.setAccessible(true);
return(LoggingSystem)constructor.newInstance(classLoader);
}
catch(Exceptionex){
thrownewIllegalStateException(ex);
}
}

LoggingSystemFactory是一个接口,它的实现类在spring-boot-start有4个,其中3个是在内部内类实现,DelegatingLoggingSystemFactory(JavaLoggingSystem,Log4J2LoggingSystem,LogbackLoggingSystem,内部类实现)。上面SYSTEM_FACTORY的实现就是DelegatingLoggingSystemFactory这个类,如下代码中delegates的值为JavaLoggingSystem,Log4J2LoggingSystem,LogbackLoggingSystem;三个类具体的加载逻辑在SpringFactoriesLoader.loadFactories函数中,最终返回的loggingSystem就是前面函数返回列表中的第一个;SpringFactoriesLoader.loadFactories 才是决定springboot默认会使用哪个日志组件关键:该类是spring的核心组件类,在spring-core包中,org.springframework.core.io.support.SpringFactoriesLoader;loggingSystem的值=LogbackLoggingSystem

publicinterfaceLoggingSystemFactory{

/**
*Returnaloggingsystemimplementationor{@codenull}ifnologgingsystemis
*available.
*@paramclassLoadertheclassloadertouse
*@returnaloggingsystem
*/
LoggingSystemgetLoggingSystem(ClassLoaderclassLoader);

/**
*Returna{@linkLoggingSystemFactory}backedby{@codespring.factories}.
*@returna{@linkLoggingSystemFactory}instance
*/
staticLoggingSystemFactoryfromSpringFactories(){
returnnewDelegatingLoggingSystemFactory(
(classLoader)->SpringFactoriesLoader.loadFactories(LoggingSystemFactory.class,classLoader));
}

}
classDelegatingLoggingSystemFactoryimplementsLoggingSystemFactory{

privatefinalFunction<ClassLoader,List<LoggingSystemFactory>>delegates;

/**
*Createanew{@linkDelegatingLoggingSystemFactory}instance.
*@paramdelegatesafunctionthatprovidesthedelegates
*/
DelegatingLoggingSystemFactory(Function<ClassLoader,List<LoggingSystemFactory>>delegates){
this.delegates=delegates;
}

@Override
publicLoggingSystemgetLoggingSystem(ClassLoaderclassLoader){
List<LoggingSystemFactory>delegates=(this.delegates!=null)?this.delegates.apply(classLoader):null;
if(delegates!=null){
for(LoggingSystemFactorydelegate:delegates){
LoggingSystemloggingSystem=delegate.getLoggingSystem(classLoader);
if(loggingSystem!=null){
returnloggingSystem;
}
}
}
returnnull;
}

}

看完上述内容,你们对怎么在springboot中设置默认日志框架有进一步的了解吗?如果还想了解更多知识或者相关内容,请关注恰卡编程网行业资讯频道,感谢大家的支持。

发布于 2021-03-17 20:54:06
收藏
分享
海报
0 条评论
155
上一篇:CSS的多种背景及使用场景和技巧 下一篇:CSS伪类修改input选中样式的方法
目录

    0 条评论

    本站已关闭游客评论,请登录或者注册后再评论吧~

    忘记密码?

    图形验证码