spring5新特性之日志体系

上一篇文章中介绍了Java日志体系,本篇就来说下spring5中使用的日志体系。

在介绍spring5中的日志体系前,先来介绍下spring4的,这两个版本有很大区别。

spring4.* 日志技术实现

查看spring-context-4.1.9.jar包依赖,可以发现spring4底层依赖了commons-logging.jar,所以我们猜想spring4日志体系是基于原生jcl框架实现。
spring5新特性之日志体系_第1张图片
下面我们来测试下,通过Javaconfig方式启动spring查看内部打印日志信息:
Dependency:

 
	org.springframework
	spring-context
	4.1.9.RELEASE

Code:

public class AppConfig {}
import com.hh.app.AppConfig;
import org.springframework.context.annotation.AnnotationConfigApplicationContext;
public class Test {
    public static void main(String[] args) {
        AnnotationConfigApplicationContext context = new AnnotationConfigApplicationContext(AppConfig.class);
        context.start();
    }
}

spring4-jul
引入log4j的jar包,再次启动:
spring4-log4j
可以看出第一次打印的日志是jul的样式,第二次打印的日志是log4j样式。

通过查看红框中标注的 AnnotationConfigApplicationContext prepareRefresh()源码,来看下spring本身的日志技术实现。全局搜索prepareRefresh(),发现该方法存在于AbstractApplicationContext,是AnnotationConfigApplicationContext的父类。
spring5新特性之日志体系_第2张图片
可以发现底层使用的日志框架为原生的jcl,从而证实了上面的结论,下面我们来看下spring5中使用的日志技术。

spring5.* 日志技术实现

将上面例子中的spring依赖改为spring-context-5.0.9.RELEASE可以发现,不管加不加log4j的依赖,都是使用的jul来打印日志,这里不在证实,读者可自行证实。下面直接通过看源码,来了解spring5.*的日志技术实现:
spring5新特性之日志体系_第3张图片
通过搜索prepareRefresh(),可以看到spring5.x中的logger是在构造方法中初始化的,而且特别要注意的是虽然日志类的路径是jul里的,但是包名却是spring-jcl,说明spring5.x中可能将jcl给改写了,并保持了原来的文件命名和路径。

进入LogFactory.getLog(this.getClass())


通过这两部分源码,可以发现spring5中默认是使用jul来打印日志。并采用循环优先的原则,按照log4j2>slf4j的顺序加载项目中的依赖,如果加载到log4j2则使用log4j2作为日志实现,如果只扫描到slf4j则将slf4j+绑定器 作为日志技术实现。当然具体的实现逻辑,需要进入源码中细看,有兴趣的读者请自行查看。

需要注意的事,如果项目中依赖了slf4j,则不能绑定slf4j-jcl,因为spring5中默认是使用jul来输出日志,如果再通过slf4j-jcl绑定jcl,则就会有两个jul日志框架,会出现java.lang.StackOverflowError异常。

objc[778]: Class JavaLaunchHelper is implemented in both /Library/Java/JavaVirtualMachines/jdk1.8.0_144.jdk/Contents/Home/bin/java (0x1012a14c0) and /Library/Java/JavaVirtualMachines/jdk1.8.0_144.jdk/Contents/Home/jre/lib/libinstrument.dylib (0x10131b4e0). One of the two will be used. Which one is undefined.
Exception in thread "main" java.lang.StackOverflowError
	at java.util.concurrent.ConcurrentHashMap.get(ConcurrentHashMap.java:936)
	at org.slf4j.impl.JCLLoggerFactory.getLogger(JCLLoggerFactory.java:73)
	at org.slf4j.LoggerFactory.getLogger(LoggerFactory.java:358)

通过对比可以看出,spring5中的日志体系更加强大了,通过循环优先机制优先扫描log4j2以及slf4j+绑定器的方式可以与市面上各种主流日志框架进行集成,从而方便的使用各种日志技术。


------------本文结束感谢您的阅读------------

你可能感兴趣的:(spring)