源码:
public static void initLogging(ServletContext servletContext) { // 首先检查是否暴露系统属性,默认是暴露 if (exposeWebAppRoot(servletContext)) { WebUtils.setWebAppRootSystemProperty(servletContext); } //得到自定义的log4j配置文件位置 String location = servletContext.getInitParameter(CONFIG_LOCATION_PARAM); if (location != null) { // 主要是获取log4j配置文件的真实路径 try { // Resolve property placeholders before potentially resolving a real path. location = ServletContextPropertyUtils.resolvePlaceholders(location, servletContext); // 判断是否是资源路径,以classpath:" or "file:"开头 if (!ResourceUtils.isUrl(location)) { // 获取配置文件的真实路径 location = WebUtils.getRealPath(servletContext, location); } // Write log message to server log. servletContext.log("Initializing log4j from [" + location + "]"); // 读取 log4jRefreshInterval 属性 String intervalString = servletContext.getInitParameter(REFRESH_INTERVAL_PARAM); if (StringUtils.hasText(intervalString)) { try { long refreshInterval = Long.parseLong(intervalString); //配置log4j并启动一个监控线程 org.springframework.util.Log4jConfigurer.initLogging(location, refreshInterval); } catch (NumberFormatException ex) { throw new IllegalArgumentException("Invalid 'log4jRefreshInterval' parameter: " + ex.getMessage()); } } else { //配置log4j org.springframework.util.Log4jConfigurer.initLogging(location); } } catch (FileNotFoundException ex) { throw new IllegalArgumentException("Invalid 'log4jConfigLocation' parameter: " + ex.getMessage()); } } } //设置WebAppRoot属性 public static void setWebAppRootSystemProperty(ServletContext servletContext) throws IllegalStateException { Assert.notNull(servletContext, "ServletContext must not be null"); String root = servletContext.getRealPath("/"); if (root == null) { throw new IllegalStateException( "Cannot set web app root system property when WAR file is not expanded"); } String param = servletContext.getInitParameter(WEB_APP_ROOT_KEY_PARAM); String key = (param != null ? param : DEFAULT_WEB_APP_ROOT_KEY); String oldValue = System.getProperty(key); if (oldValue != null && !StringUtils.pathEquals(oldValue, root)) { throw new IllegalStateException( "Web app root system property already set to different value: '" + key + "' = [" + oldValue + "] instead of [" + root + "] - " + "Choose unique values for the 'webAppRootKey' context-param in your web.xml files!"); } System.setProperty(key, root); servletContext.log("Set web app root system property: '" + key + "' = [" + root + "]"); }源码流程解析
1.exposeWebAppRoot判断是否暴露WebAppRoot,默认是暴露.可以自定义,如下配置
<context-param> <param-name>log4jExposeWebAppRoot</param-name> <param-value>true</param-value> </context-param>2.如果暴露,将设置系统属性为 webapp.root = servletContext.getRealPath("/")(项目部署根路径),也可以自定义webAppRootKey,如下
<context-param> <param-name>webAppRootKey</param-name> <param-value>logtopic.root</param-value> </context-param>这样就会设置系统属性 logtopic.root = servletContext.getRealPath("/"),再配置文件中就可以用${logtopic.root}代替部署根路径