大家注意到了么,你只需要把log4j的文件放到classpath下,它就会自动加载,这是为什么呢?
今天带大家一探究竟!
先要从org.apache.log4j.LogManager谈起,进入类中看它的代码:大家一定恍然大悟。
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+"]."); } } }
从代码至上而下说起:
/** Search for the properties file log4j.properties in the CLASSPATH. */
看这句从CLASSPATH下查找log4j.properties的文件,以下的都是围绕这句话的。
// if there is no default init override, then get the resource
// specified by the user or the default config file.
1,这句如果没有对默认初始化的重写,就加载这个用户制定的log4j.properties或默认的配置文件。
// if the user has not specified the log4j.configuration
// property, we search first for the file "log4j.xml" and then
// "log4j.properties",
2,如果用户没有制定log4j.configuration的属性,就首先加载log4j.xml,若无再接着在加载log4j.properties
所以,你把log4j.xml或log4j.properties放在这些目录下,那么log4j会“自动去加载”到,不用程序里手工写加载代码了。
但我个人,还是倾向于自己写加载。因为这种“悄悄被人做掉”,一是代码很难理解,二是假如A同学放了一个log4j,B同学又写了一个放在其他目录,这种默认加载机制,不一定哪个生效及生效顺序。这种不确定性,还是自己写两行代码,消灭在摇篮里吧。自己加载可以参考我的另一篇博客。