1.我们常见的日志框架 有log4j ,jul, jcl,slf4j,logback 等等
下面我就把这几个框架给简要说下
1>log4j 加入log的jar以及log4j的配置文件
<dependency>
<groupId>log4j</groupId>
<artifactId>log4j</artifactId>
<version>1.2.16</version>
</dependency>
#配置文件
log4j.rootLogger=INFO,stdout
# 输出控制台
log4j.appender.stdout=org.apache.log4j.ConsoleAppender
log4j.appender.stdout.Target=System.out
log4j.appender.stdout.layout=org.apache.log4j.PatternLayout
log4j.appender.stdout.layout.ConversionPattern=[%p]%d{yyyy-MM-dd HH:mm:ss} %l - %m%n
看啊 打印出来是白色的
做一个记录 log4j打印出来的是白色的日志
java可以不用第三方日志 用jul------->这个是java自带的 看包名
jul打印出来是红色的
3> 接下来说一个比较牛逼的日志框架 乃至大名鼎鼎的Spring都采用的它
叫做jcl
-------------------------------->
看啊此时的pom中的jar 有2个,1个是jcl 一个是log4j
看是白色的 猜想下jcl是通过log4j打印日志。验证的话可以吧log4j的日志调高点比方说error 这个话就不会打印日志了
我们也可以打个断点看看这个对象名叫做Log4jLogger
=======================>
好了现在剔除log4j的jar会怎么样呢
此时日志
此时日志是红色的
并且这个名字叫做jdk14Logger
对吧 也就是说现在在有log4j的情况下 jcl通过log4j打印日志 如果在没有log4j的依赖下 jcl通过jul打印日志,也就是java自带的吧
下面下面 我们就说一下jcl的源码解析
点进去看看
此处是因为getfactory()都一样 所以就不看里面的方法 具体看getInstance(name)
------------>下一步啊
接下来锁定这个方法—>看名字discoverLogImplementation 发现日志实现
到最后锁定他
for(;;) {
logDiagnostic("Trying to load '" + logAdapterClassName + "' from classloader " + objectId(currentCL));
Class c;
//---->数组对象中传递过来的
c = Class.forName(logAdapterClassName, true, currentCL);
///------------>获取对象的构造函数
constructor = c.getConstructor(logConstructorSignature);
---------》根据构造函数new对象
Object o = constructor.newInstance(params);
if (o instanceof Log) {
logAdapterClass = c;
logAdapter = (Log) o;
break;
}
我们现在可以看看数组对象中有哪些东西
LOGGING_IMPL_LOG4J_LOGGER,
"org.apache.commons.logging.impl.Jdk14Logger",
"org.apache.commons.logging.impl.Jdk13LumberjackLogger",
"org.apache.commons.logging.impl.SimpleLog"
for(int i=0; i<classesToDiscover.length && result == null; ++i) {
result = createLogFromClass(classesToDiscover[i], logCategory, true);
}
如果找到了就是用使用break停止死循环
现在再看这个for循环 他是 通过一个数组的顺序,判断是否能够加载到具体的实现,如果找到了直接使用退出循环
------------------------------->jcl的出现让我们的代码耦合程度降低
但是jcl已经让apache淘汰了
现在有更好的日志技术可以替换他 ----->slf4j
---------------------- >我们看下他的官网
slf4j 有绑定器这个感念 意思是说
这个就比较多了啊 这个绑定器
按照官网的说我加入了一个log4j的绑定器
--------------->这个就是绑定器slf4j也一样自己不打印日志 通过使用第三方的日志框架绑定, 只不过他的绑定器比较多 比方说 log4,log4j2,logback,等等
比jcl更加抽象吧
---------------------------->
但是啊有一天 你的项目的日志架构
app--------->slf------------>jul------------>打印日志
Spring的日志
spring—>jcl------------>log4j打印日志
你的项目要引入Spring框架后就会有2个日志体现
此时你有1种方案 就是改变你的日志体系
app---->slf---->绑定到jcl------->log4j打印日志
因为此时你不可能改变Spring源码啊
但是啊 slf4j还有桥接这么一说
就是让Spring的jcl 桥接到你的slf4j
然后打印日志就是这样子
我此时模拟一下 就是Spring-------->jcl------------->log4j
我们可以通过<dependency> <groupId>org.slf4j</groupId> <artifactId>jcl-over-slf4j</artifactId> <version>1.7.28</version> </dependency>
将jcl 桥接到slf,然后通过slf绑定到jul------------>打印日志
---------------------------------------------------->
想想 现在有这么个情况
比方说你的项目
通过slf绑定到jcl
然后Jcl再通过桥接桥接到slf
也就是说
APP1 ------->slf------->jcl
也就是说此时你的项目同时存在着3个jar包他的程序就会报错的
就会报一个死循环的错误
就是说 APP1 ------->slf------->jcl 然后再桥接到slf4j 这样一直来回走就会出现死循环的现象
https://gitee.com/itcastday10/sprign5_general_log.git 这是gitee地址