设为首页 加入收藏

TOP

Log4j2源码分析系列:(一)配置加载(二)
2019-09-17 16:28:17 】 浏览:39
Tags:Log4j2 源码 分析 系列 配置 加载

好了,回到加载配置的方法,可以看到426行代码判断是否支持所有文件类型。其实最终的核心代码是453~467行:

这里尝试用不同的条件获取config,如果最终config为null,就会打印error日志,告诉你没有找到配置文件。由于目前我们还没有配置,就会走到466行。

 

现在,你可以在/resources路径下增加一个log4j2文件,填写一下简单配置,就会在459行得到config了。我们来看看getConfiguration的细节:

 

 可以看出,这里就是按照各种条件拼接处配置文件的名字。

 以最常见的log4j2.xml为例:

上图中,我们已经得到了配置文件的名字:log4j2.xml。

同时可以看到,prefix为log4j2,suffix为文件后缀。

其中prefix(505行)是写死在ConfigurationFactory中的:

所以,我们配置时定义的文件名,需要遵循规范,而不能随意命名。 

现在有了配置文件名,就可以加载了:

进入方法内部: 

现在,url已经获取到了。它的值是"项目路径/target/classes/log4j2.xml"。

后面的事情就是从文件加载内容( 517行,涉及到类加载器的知识,请自行查看)。

再然后,就是读取xml文件的内容啦:

走到这里,就开始读取xml文件了。这部分内容且待下回分解。 

 

遗留问题:LoggerManager的factory及其内部的selector是怎么初始化的?

其实,在调用LogManager.getContext(cl, false);之前,LoggerManager中的静态代码块会提前被调用,我们看一下:

 

我们看89~100行代码即可:

进入方法ProviderUtil.getProviders()内部查看:

可以看到provider是使用懒汉方式实现的单例(你会发现89行代码中ProviderUtil.hasProviders()方法执行时已经创建过了,因此这里直接返回。注意创建过程有个细节,后面要用到),用于确定各个factory的优先级。

我们重点看91行代码内部细节:

在96行,加载class,98行又将其转换为LoggerContextFactory的子类(也就是Log4jContextFactory)。

那么问题来了,className是啥,为啥它指定了Log4jContextFactory?

其实,在前面创建Provider实例时,构造器中会读取log4j-core中的配置文件,其中就包含className对应的属性:

就这样,得到了className:org.apache.logging.log4j.core.impl.Log4jContextFactory。

接着往下走:

可以看到这里会用反射的方式实例化Log4jContextFactory对象,会调用Log4jContextFactory的无参构造器:

createContextSelector方法,就会初始化selector啦:

后续的初始化细节就不再展开啦。

最后会走到这里:

至此,factory创建完毕。

 

现在,你应该可以回答文首的三个问题了吧?

总结

本文通过调试,描述了log4j2日志配置加载的主线(忽略了很多细节,比如可以配置path等等),后续的文章将会进一步描述配置文件的解析过程。 

希望读者通过本文,能够对log4j2的配置加载过程有更为深入的理解。

 

最后,作者水平有限,难免错漏,欢迎指正及交流,共同进步。

?
首页 上一页 1 2 下一页 尾页 2/2/2
】【打印繁体】【投稿】【收藏】 【推荐】【举报】【评论】 【关闭】 【返回顶部
上一篇报错:ORA-01461:仅能绑定要插入 .. 下一篇springboot启动报:Error creatin..

最新文章

热门文章

Hot 文章

Python

C 语言

C++基础

大数据基础

linux编程基础

C/C++面试题目