您的位置:首页 > 运维架构

Log4j.properties文件自动加载

2015-09-06 11:46 381 查看
org.apache.log4j.LogManager类有一个静态块,首先是找log4j.xml,找不到的情况下才找log4j.properties

Java code

static {
// By default we use a DefaultRepositorySelector which always returns 'h'.
Hierarchy h = new Hierarchy(new RootLogger((Level) Level.DEBUG));
repositorySelector = new DefaultRepositorySelector(h);

/** Search for the properties file log4j.properties in the CLASSPATH.  */
String override =OptionConverter.getSystemProperty(DEFAULT_INIT_OVERRIDE_KEY,
null);

// if there is no default init override, then get the resource
// specified by the user or the default config file.
if(override == null || "false".equalsIgnoreCase(override)) {

String configurationOptionStr = OptionConverter.getSystemProperty(
DEFAULT_CONFIGURATION_KEY,
null);

String configuratorClassName = OptionConverter.getSystemProperty(
CONFIGURATOR_CLASS_KEY,
null);

URL url = null;

// if the user has not specified the log4j.configuration
// property, we search first for the file "log4j.xml" and then
// "log4j.properties"
if(configurationOptionStr == null) {
url = Loader.getResource(DEFAULT_XML_CONFIGURATION_FILE);
if(url == null) {
url = Loader.getResource(DEFAULT_CONFIGURATION_FILE);
}
} else {
try {
url = new URL(configurationOptionStr);
} catch (MalformedURLException ex) {
// so, resource is not a URL:
// attempt to get the resource from the class path
url = Loader.getResource(configurationOptionStr);
}
}

// If we have a non-null url, then delegate the rest of the
// configuration to the OptionConverter.selectAndConfigure
// method.
if(url != null) {
LogLog.debug("Using URL ["+url+"] for automatic log4j configuration.");
OptionConverter.selectAndConfigure(url, configuratorClassName,
LogManager.getLoggerRepository());
} else {
LogLog.debug("Could not find resource: ["+configurationOptionStr+"].");
}
}
}


换句话说,是什么呢?也就是说:

1. 获取系统属性,看是否用户设置了override。默认是不设置的。

2. 如果确实没有设置,那么尝试找一下,有没有log4j.xml,有则加载。

3. 如果还没有,那么尝试找一下,有没有log4j.properites,有则加载。

其中,2、3里提到的“尝试找一下”,可能是去哪个目录里面找呢?翻译了一下,效果不好,还是上原文清晰 :

Search for 
resource
 using the thread context class loader under Java2. If that fails, search for 
resource
 using
the class loader that loaded this class (
Loader
). Under JDK 1.1, only the the class loader that loaded this class (
Loader
) is used.
Try one last time with 
ClassLoader.getSystemResource(resource)
, that is is using the system class loader in JDK 1.2 and virtual machine's built-in class
loader in JDK 1.1. 

 

所以,你把log4j.xml或log4j.properties放在这些目录下,那么log4j会“自动去加载”到,不用程序里手工写加载代码了。

2,然后是怎么找呢:如下代码,是委托给classloader(加载Loader类的classloader)去找了,

Java code
      // We could not find resource. Ler us now try with the
// classloader that loaded this class.
classLoader = Loader.class.getClassLoader();
if(classLoader != null) {
LogLog.debug("Trying to find ["+resource+"] using "+classLoader
+" class loader.");
url = classLoader.getResource(resource);
if(url != null) {
return url;
}
}

3,classloader的getResource(...)又是怎么找呢:总是先从父classloader里去找,找不到才自己去找

Java code
    public URL getResource(String name) {
URL url;
if (parent != null) {
url = parent.getResource(name);
} else {
url = getBootstrapResource(name);
}
if (url == null) {
url = findResource(name);
}
return url;
}

总结:对于不同的应用服务器(或者web服务器)来说,classloader的层次不尽相同。这里以最简单的tomcat来说,如果你的应用是部署到tomcat下的,使用log4j配置文件的顺序就是$TOMCAT_HOME/lib/log4j.xml或者log4j.properties==>你自己web应用/WEB-INF/classes(或者lib)/log4j.xml或者log4j.properties.
对于WEB-INF下是classes优先还是lib优先 你可以自己测试一下。
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签:  log4j