log4j,如何“自動加載”?


今天看代碼,發現log4j.properties。沒有相應的加載代碼,但它卻生效了,這多神奇!

 

看進去,org.apache.log4j, LogManager.java,其有一個static方法塊:

  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里提到的“嘗試找一下”,可能是去哪個目錄里面找呢?翻譯了一下,效果不好,還是上原文清晰 :

  1. 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.
  2. 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會“自動去加載”到,不用程序里手工寫加載代碼了。

但我個人,還是傾向於自己寫加載。因為這種“悄悄被人做掉”,一是代碼很難理解,二是假如A同學放了一個log4j,B同學又寫了一個放在其他目錄,這種默認加載機制,不一定哪個生效及生效順序。這種不確定性,還是自己寫兩行代碼,消滅在搖籃里吧。

 


免責聲明!

本站轉載的文章為個人學習借鑒使用,本站對版權不負任何法律責任。如果侵犯了您的隱私權益,請聯系本站郵箱yoyou2525@163.com刪除。



 
粵ICP備18138465號   © 2018-2025 CODEPRJ.COM