引言
下面我来讲一个情景来引出我们的日志框架的使用案例及其由来:
程序猿小刘同学开发一个大型的项目:
首先他经常会使用System.out.println("");将关键的数据打印在控制台上,此时很容易来观看数据的存在状态,然而项目要上线的时候这种情况又是比较烦人的,很多的情况下经理说这样对程序的实现不好,限时来把相对应的给去掉,小刘同学就马上给抓紧时间给去掉呀,这忙的呀累的很,刚去完,这个时候经理又说了:小刘,不用去了,留下来吧,我看着这个玩意挺好的,咱们留下来也挺好,这个时候小刘心里很不爽,心里在想有没有办法能够实现其相对应的功能能够实现其相对于的功能能够实现随着自己的想法来做呢,这个时候就自然而然的想起来自己也开发一个记录相关的日志框架吧
然后好景不长,过两天项目经理说了又提出了新的需求,能不能添加几个新的框架,比如自动归档呀,异步模式呀,此时突然发现手上的日志框架又不满足需求,然后又吧唧吧唧开发新的框架来实现功能
最后小刘同学一想这样不行呀,能不能像JDBC数据库驱动一样,写一个统一的接口类(日志的一个抽象层),然后我们想用什么类型的实现我们就做不同的日志实现就行了,这样不就是完美的解决了这样的问题了嘛,这个时候小刘同学就是一顿操作了,这句诗日志门面和日志实现的由来
日志门面 | 日志实现 |
---|---|
JCL(JAkarta Commons Logging) ,SLF4J,JBOSS Logging | Log4j,JUL(java.util.logging,Log4j2,Logback) |
我们使用的话一般就是从左边选择一个,然后从右边选择一个,本篇博客咱们主要是讲解SpringBoot的对日志框架的使用,看过源码后可以知道SpringBoot选择的是slf4j和logback
slf4j桥接原理
SLF4J,即简单日志门面(Simple Logging Facade for Java),不是具体的日志解决方案,它只服务于各种各样的日志系统.按照官方的说法,SLF4J是一个用于日志系统的Facade,允许最终用户在部署其应用时使用其所希望的日志System.
#使用方法
Logger logger = LoggerFactory.getLogger(CtrTask.class);
logger.info("本次投递数量:" + users.size());
#调用过程
public static Logger getLogger(String name) {
ILoggerFactory iLoggerFactory = getILoggerFactory();
return iLoggerFactory.getLogger(name);
}
public static ILoggerFactory getILoggerFactory() {
if (INITIALIZATION_STATE == UNINITIALIZED) {
INITIALIZATION_STATE = ONGOING_INITIALIZATION;
//查找实现类
performInitialization();
}
...
return StaticLoggerBinder.getSingleton().getLoggerFactory();
...
}
private static String STATIC_LOGGER_BINDER_PATH = "org/slf4j/impl/StaticLoggerBinder.class";
private static Set findPossibleStaticLoggerBinderPathSet() {
...
paths = ClassLoader.getSystemResources(STATIC_LOGGER_BINDER_PATH);
...
}
日志系统桥接器是个巧妙的解决方案,有些库的作者在引用第三方库的时候,也碰到了日志系统混乱的问题,并顺手用桥接器解决了,只不过碰巧跟你桥接的目标不一样,桥接到了log4j
如何让系统中所有的日志都统一到slf4j;
1、将系统中其他日志框架先排除出去;
2、用中间包来替换原有的日志框架;
3、我们导入slf4j其他的实现
SpringBoot底层实现原理
1.引入其常用的jar包
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter</artifactId>
</dependency>
2.观察其源码我们可以知道我们其主要使用的是logging
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-logging</artifactId>
</dependency>
3.观看其相对应的底层调用关系