Log4j容器初始化探究

Log4j容器初始化探究

Log4j第一步就是初始化Logger容器Repository,这一章我们来探究Logger容器,从别从独立应用以及servlet容器下启动初始化两方面探究。

1 独立应用

静态初始化,Java语言保证静态初始化只被执行一次,静态初始化源码在LogManager中。

时序图:

Log4j容器初始化探究

初始化流程:

第一步: LogManager获取配置文件的URL

第二步: OptionConverter获取Configurator实现类(配置类)

第三步: Configurator读取配置文件内容,配置Logger容器(默认配置Hierarchy)

1.1 LoggManager探究

LogManager获取配置文件的URL

源码:

//只在内部使用,将来版本将变为protected级别。 static public final String DEFAULT_CONFIGURATION_FILE = "log4j.properties"; static final String DEFAULT_XML_CONFIGURATION_FILE = "log4j.xml"; //将来版本变为private级别 public String DEFAULT_CONFIGURATION_KEY="log4j.configuration"; //将来版本将变为private级别。用来指定在定义配置类 static final public String CONFIGURATOR_CLASS_KEY="log4j.configuratorClass"; //将来版本将变为private级别。如果不为空并且不为`false`则直接跳过初始化阶段 public static final String DEFAULT_INIT_OVERRIDE_KEY = "log4j.defaultInitOverride"; static private Object guard = null; //Logger容器选择器 static private RepositorySelector repositorySelector; static { //初始化Logger容器为Hierarchy。根节点是RootLogger,默认级别是DEBUG Hierarchy h = new Hierarchy(new RootLogger((Level) Level.DEBUG)); //初始化Logger容器选择器,以Hierarchy为Logger容器 repositorySelector = new DefaultRepositorySelector(h); //获取系统属性log4j.defaultInitOverride String override =OptionConverter.getSystemProperty(DEFAULT_INIT_OVERRIDE_KEY,null); //如果没有设置log4j.defaultInitOverride,或者log4j.defaultInitOverride为false,进入初始化流程,否则跳过初始化 if(override == null || "false".equalsIgnoreCase(override)) { //读取系统属性log4j.configuration String configurationOptionStr = OptionConverter.getSystemProperty(DEFAULT_CONFIGURATION_KEY, null); //读取系统属性log4j.configuratorClass String configuratorClassName = OptionConverter.getSystemProperty(CONFIGURATOR_CLASS_KEY, null); URL url = null; //如果不存在log4j.configuration if(configurationOptionStr == null) { //第一步先检查是否有log4j.xml url = Loader.getResource(DEFAULT_XML_CONFIGURATION_FILE); //如果没有检查是否有log4j.properties if(url == null) { url = Loader.getResource(DEFAULT_CONFIGURATION_FILE); } } else { try { url = new URL(configurationOptionStr); } catch (MalformedURLException ex) { url = Loader.getResource(configurationOptionStr); } } if(url != null) { LogLog.debug("Using URL ["+url+"] for automatic log4j configuration."); try { //如果存在url,则利用URL配置Logger容器 OptionConverter.selectAndConfigure(url, configuratorClassName,LogManager.getLoggerRepository()); } catch (NoClassDefFoundError e) { LogLog.warn("Error during default initialization", e); } } else { LogLog.debug("Could not find resource: ["+configurationOptionStr+"]."); } } else { LogLog.debug("Default initialization of overridden by " + DEFAULT_INIT_OVERRIDE_KEY + "property."); } }

源码流程解析:

1.初始化Logger容器Hierarchy,设置根节点为RootLogger

2.初始LoggerRepositorySelector(容器选择器)为默认的DefaultRepositorySelector,容器为Hierarchy

3.读取系统属性log4j.defaultInitOverride,如果没有设置或者为false进行初始化,否则跳过初始化

4.读取系统属性log4j.configuration(log4j文件路径配置),如果存在对应的文件,则得到URL.如果没有对应的文件,首先检查是否存在log4j.xml文件,如果存在,得到Log4j配置文件URL,如果不存在log4j.xml,继续检查是否存在log4j.properties文件,如果存在该文件,得到log4j配置文件的URL,否则提示没有发现配置文件。

5.读取系统属性log4j.configuratorClass(自定义Configurator配置类全路径,一般不自定义)

6.调用OptionConverter.selectAndConfigure(url, configuratorClassName,LogManager.getLoggerRepository()),初始化logger容器

1.2 OptionConverter探究

OptionConverter获取Configurator实现类(配置类)

内容版权声明:除非注明,否则皆为本站原创文章。

转载注明出处:https://www.heiqu.com/ef6d46734fd2100317cd4711a13b5bc1.html