Spring5.0 新特性之日志框架

1 日志框架场景:

某项目开发人员二蛋,为了了解项目运行情况,在我们代码中加入了,System.out.println("*****")来记录 日志,有一天, 项目经理觉得通过这种,System.out.println("*****")的方式很 low,要他把把代码中的,System.out.println 给去掉,但是过了几天之后,项目出问题了,查询很棘手又没有日志,然后经理又要求他把 System.out.println 加上...然后又去掉...又加上...

情况一: 二蛋是一个脾气暴躁的人,拿起板砖就跟经理干起来,然后牢底坐穿...全剧终... 没用案例场景...下课...

情况二: 二蛋为了解决 System.out.println("*****")比较 low 的情况,然后就写了一个记录日志的 jar 包名称叫 angle-logging.jar 用来替代 System.out.println("*****"),二蛋是一个爱专研的人,想出了一写比较牛逼的点子...比如日志异步记录, 日志归档...然后 起名叫 angle-logging-good.jar, 然后把项目中原来的 angle-logging.jar 中的卸下来,然后安装新的框架 angle-logging-good.jar,但是 由于二种方式实现的接口可能不一样,需要修改代码中的日志打印类。这种情况 这么办?此时二蛋,想到了一个好的点子,我把angle-logging.jar 和 angle-logging-good.jar 的功能都抽取出来形 成一个门面 angle-logging-intf.ja(r 也就是我们的接口)

然后在二个日志框架中实现不同的功能.这 样,我的业务代码中直接使用的是我们的 angle-logging-intf.jar 的方法, 然后根据需要导入了 angle- logging.jar 或者 angle-logging-good.jar

2 我们 Java 中常用的日志框架是什么?

2.1 我们常常听说的就是如下的日子框架,还不知道怎么选?

(1) JUL(java.util.logging) ,

(2) JCL(Jakarta Commons-Logging) 由 apache 公司 Jakarta 小组开发的,

(3) JBoss-logging

(4) logback

(5) log4j

(6) log4j2

(7) slf4j(Simple Logging Facade for Java.)

Spring5.0 新特性之日志框架

我们 Spring 底层选择的是我们的这个 JCL 做为日志门面的 SpringBoot 选择的是 SLF4J 做为我们的日志门面(当时 log4j,和 logback)他选择了 logback

Spring5.0 新特性之日志框架

2.2 加入我们系统使用的是 SLF4J 作为日志门面,我们是如何匹配?

1) app(我们的应用系统)+日志门面(Slf4j slf4j-api.jar)+不加我们的日志实现 不会记录日志

2) app(我们的应用系统)+日志门面(Slf4j slf4j-api.jar)+logback(logback-classic.jar,logback-core.jar)

3) app(我们的应用系统)+日志门面(Slf4j slf4j-api.jar)+适配器(因为早期 log4j 压根不知道有一slf4j 的日志门面,所以降入适配器slf4j-log412.jar 实现我们slf4j 的接口,真正实现功能调用我们的 log4j.jar)+log4j.jar

4) app(我们的应用系统)+日志门面(Slf4j slf4j-api.jar)+适配器(因为早期 juc 压根不知道有一 slf4j 的 日志门面,所以降入适配器 slf4j-jdk14.jar 实现我们 slf4j 的接口,真正实现功能调用我们的 juc 的 jar 包的功 能)+juc.jar

5) app(我们的应用系统)+日志门面(Slf4j slf4j-api.jar)+slf4j(slf4j-simple.jar)

2.2.1 第一种情况

(我们业务系统直接使用的是 spring 底层用的日志框架 jcl+jdk 的日志实现)



org.springframework
spring-context
4.3.20.RELEASE

public class MainClass {
private static Logger logger = Logger.getLogger(MainClass.class.getName()); public static void main(String[] args) {
AnnotationConfigApplicationContext ctx = new AnnotationConfigApplicationContext(MainConfig.class);
logger.info("hello tuling"); ctx.start();
}
}
 

打印的日志格式是:(我们发现都是红色的)

Spring5.0 新特性之日志框架

2.2.2 第二种情况

(我们往 pom 依赖中加入 log4j 的包以及加入 log4j 的配置文件,spring 底层的日志门面使用的是 jcl,实现貌似 使用了是 log4j 的格式)



org.springframework
spring-context
4.3.20.RELEASE

 


log4j
log4j
1.2.17

 
import org.apache.log4j.Logger;
 
private static Logger logger = Logger.getLogger(MainClass.class.getName()); public static void main(String[] args) {
AnnotationConfigApplicationContext ctx = new AnnotationConfigApplicationContext(MainConfig.class);
logger.info("hello tuling"); ctx.start();
}
 

日志打印情况:

Spring5.0 新特性之日志框架

2.2.3 第三种情况

(我们往容器中导入了是 slf4j 的门面,使用 log4j 的实现)


slf4j 的门面

org.slf4j
slf4j-api
1.7.10

 
该包是转换包,实现 slf4j-api 接口,调用 log4j 的实现

org.slf4j
slf4j-log4j12
1.7.10

 
log4j 的日志实现

log4j
log4j
1.2.17

 
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
 
public class MainClass {
private static Logger logger = LoggerFactory.getLogger(MainClass.class);
//private static Logger logger = Logger.getLogger(MainClass.class.getName());
 
public static void main(String[] args) {
AnnotationConfigApplicationContext ctx = new AnnotationConfigApplicationContext(MainConfig.class);
logger.info("hello tuling"); ctx.start();
}
}
 

日志打印情况:

Spring5.0 新特性之日志框架

2.2.4 第四种情况

我们往容器中导入了是 slf4j 的门面,使用 logback 的实现加入的依赖:



ch.qos.logback
logback-core
1.1.2


ch.qos.logback
logback-classic
1.1.2


org.slf4j
slf4j-api
1.7.7

 
import org.slf4j.Logger;
import org.slf4j.LoggerFactory; public class MainClass {
private static Logger logger = LoggerFactory.getLogger(MainClass.class);
//private static Logger logger = Logger.getLogger(MainClass.class.getName());
 
public static void main(String[] args) {
AnnotationConfigApplicationContext ctx = new AnnotationConfigApplicationContext(MainConfig.class);logger.info("hello tuling");ctx.start();
}
}

Spring5.0 新特性之日志框架

3 Spring4.Xspring 底层使用的日志技术

Spring5.0 新特性之日志框架

我们从这里可以看出来,spring4.x 获取的日志对象中,LOGGer 对象是 jCL 的,而他底层搭配的技术点就是先去找 log4j 的日志实现,若没有找到,底层去找 jdk 的日志框架。压根不支持 logback,log4j2 的日志技术。

4 Spring5.x 底层使用的日志技术


private static LogApi logApi = LogApi.JUL; static {
ClassLoader cl = LogFactory.class.getClassLoader(); try {
//第一步:先尝试去加载 log4j2 的日志框架cl.loadClass("org.apache.logging.log4j.spi.ExtendedLogger"); logApi = LogApi.LOG4J;
} catch (ClassNotFoundException ex1) { try {
//第二步:尝试去加载
LogApi.SLF4J_LAL cl.loadClass("org.slf4j.spi.LocationAwareLogger"); logApi = LogApi.SLF4J_LAL;
} catch (ClassNotFoundException ex2) {//尝试去加载 slf4j 的日志实现cl.loadClass("org.slf4j.Logger"); logApi = LogApi.SLF4J;} catch (ClassNotFoundException ex3) {//使用原生的 JUL}}}}public static Log getLog(String name) { switch (logApi) {case LOG4J:return Log4jDelegate.createLog(name); case SLF4J_LAL:return Slf4jDelegate.createLocationAwareLog(name); case SLF4J:return Slf4jDelegate.createLog(name); default:// Defensively use lazy-initializing delegate class here as well since the// java.logging module is not present by default on JDK 9. We are requiring// its presence if neither Log4j nor SLF4J is available; however, in the// case of Log4j or SLF4J, we are trying to prevent early initialization// of the JavaUtilLog adapter - e.g. by a JVM in debug mode - when eagerly// trying to parse the bytecode for all the cases of this switch clause. return JavaUtilDelegate.createLog(name);}}

文章到这就结束了,本文只是spring笔记的一部分,如需要,可关注微信公众号“老周扯IT”

Spring5.0 新特性之日志框架

展开阅读全文

页面更新:2024-04-10

标签:框架   日志   适配器   门面   底层   接口   情况   代码   功能   系统

1 2 3 4 5

上滑加载更多 ↓
推荐阅读:
友情链接:
更多:

本站资料均由网友自行发布提供,仅用于学习交流。如有版权问题,请与我联系,QQ:4156828  

© CopyRight 2008-2024 All Rights Reserved. Powered By bs178.com 闽ICP备11008920号-3
闽公网安备35020302034844号

Top