log4j加载配置文件原理

public class LogManager {
    
    static public final String DEFAULT_CONFIGURATION_FILE = "log4j.properties";
  
    static final String DEFAULT_XML_CONFIGURATION_FILE = "log4j.xml"; 
    
    static final public String DEFAULT_CONFIGURATION_KEY="log4j.configuration";
  
    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)) {

            //查的System中是否有属性log4j.configuration,实际是通过System.getProperty("log4j.configuration",null)获得
            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"
            //如果不存在系统属性log4j.configuration,则先查找类路径下是否有log4j.xml,若没有再查找类路径下是否有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.");
                try {
                    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."); 
        }  
    }
  
}

一、log4j加载配置文件是通过LogManager完成的,由代码得到加载步骤:

    (1)查找系统属性中是否存在log4j.configuration属性,若存在,则加载log4j.configuration属性指定的文件

    (2)查找类路径是否有log4j.xml,若有,则加载log4j.xml

    (3)查找类路径是否有log4j.properties,若有,则加载log4j.properties

 

二、如何让系统属性中存在log4j.configuration属性?

    //在启动程序时通过-D可以指定系统属性

    java -Dlog4j.configuration="xxx" -jar zzz.jar 

 

三、如何指定某个文件在类路径下

    //在启动程序时通过-cp指定类路径,xxx/conf下的文件,都是作为属于类路径下,因此可以将log4j.properties放在xxx/conf下

    java -cp xxx/conf -jar zzz.jar 

 

四、查找类路径是否有某个文件的原理

public class MyLoader  { 

    static{
        ClassLoader classLoader = MyLoader.class.getClassLoader();
        URL url = classLoader.getResource("log4j.properties");
        if(url!=null){
            //获得log4j.properties的路径
            String fileDir = url.getPath();
            //log4j.properties实现热加载
            PropertyConfigurator.configureAndWatch(url.getPath(),1000);
            ...
        }
    }

}

   

你可能感兴趣的:(java)