1. 程式人生 > >【Spring】- springmvc自定義Log4j配置

【Spring】- springmvc自定義Log4j配置

浪費了“黃金五年”的Java程式設計師,還有救嗎? >>>   

Log4j 是目前專案開發中使用最廣的日誌記錄框架,一般配置Log4j只需要配置Log4j的屬性檔案在src目錄以及引入Log4j的jar包即可,但是如果專案比較大的時候,我們需要將一些配置檔案放入自定義的專案目錄裡面,傳統的方法顯然不能滿足需求。


web.xml檔案配置:

<context-param>   
      <param-name>log4jConfigLocation</param-name>   
      <param-value>classpath:config/log4j.properties</param-value>   
  </context-param>   
  <context-param>   
      <param-name>log4jRefreshInterval</param-name>   
      <param-value>6000</param-value>   
  </context-param>   
  <listener>   
      <listener-class>org.springframework.web.util.Log4jConfigListener</listener-class>   
  </listener> 
  • context-param:配置ServletContext的初始化引數
  • Log4jConfigListener:配置Log4j的監聽器

Log4jConfigListener工作原理

@Deprecated
public class Log4jConfigListener implements ServletContextListener {

	@Override
	public void contextInitialized(ServletContextEvent event) {
		Log4jWebConfigurer.initLogging(event.getServletContext());
	}

	@Override
	public void contextDestroyed(ServletContextEvent event) {
		Log4jWebConfigurer.shutdownLogging(event.getServletContext());
	}
}

Log4jConfigListener 通過實現ServletContextListener介面,隨著Servlet容器的啟動,其監聽器的contextInitialized()方法就會被呼叫,Log4jConfigListener藉助於Log4jWebConfigurer實現Log4j的初始化和關閉等操作

Log4jWebConfigurer的initLogging(ServletContext servletContext)方法:

public static void initLogging(ServletContext servletContext) {
    // Expose the web app root system property.
    if (exposeWebAppRoot(servletContext)) {
        WebUtils.setWebAppRootSystemProperty(servletContext);
    }

    // Only perform custom log4j initialization in case of a config file.
    String location = servletContext.getInitParameter(CONFIG_LOCATION_PARAM);
    if (location != null) {
        // Perform actual log4j initialization; else rely on log4j's default initialization.
        try {
            // Resolve property placeholders before potentially resolving a real path.
            location = ServletContextPropertyUtils.resolvePlaceholders(location, servletContext);

            // Leave a URL (e.g. "classpath:" or "file:") as-is.
            if (!ResourceUtils.isUrl(location)) {
                // Consider a plain file path as relative to the web application root directory.
                location = WebUtils.getRealPath(servletContext, location);
            }

            // Write log message to server log.
            servletContext.log("Initializing log4j from [" + location + "]");

            // Check whether refresh interval was specified.
            String intervalString = servletContext.getInitParameter(REFRESH_INTERVAL_PARAM);
            if (StringUtils.hasText(intervalString)) {
                // Initialize with refresh interval, i.e. with log4j's watchdog thread,
                // checking the file in the background.
                try {
                    long refreshInterval = Long.parseLong(intervalString);
                    org.springframework.util.Log4jConfigurer.initLogging(location, refreshInterval);
                }
                catch (NumberFormatException ex) {
                    throw new IllegalArgumentException("Invalid 'log4jRefreshInterval' parameter: " + ex.getMessage());
                }
            }
            else {
                // Initialize without refresh check, i.e. without log4j's watchdog thread.
                org.springframework.util.Log4jConfigurer.initLogging(location);
            }
        }
        catch (FileNotFoundException ex) {
            throw new IllegalArgumentException("Invalid 'log4jConfigLocation' parameter: " + ex.getMessage());
        }
    }
}

工作流程:將web應用絕對路徑新增到系統屬性(支援log4j ${key}等獲功能),方法內部讀取ServletContext的初始化引數然後呼叫 org.springframework.util.Log4jConfigurer.initLogging(location, refreshInterval)完成Log4j的初始化工作

Log4j關閉流程:

public static void shutdownLogging(ServletContext servletContext) {
    servletContext.log("Shutting down log4j");
    try {
        org.springframework.util.Log4jConfigurer.shutdownLogging();
    }
    finally {
        // Remove the web app root system property.
        if (exposeWebAppRoot(servletContext)) {
            WebUtils.removeWebAppRootSystemProperty(servletContext);
        }
    }
}

分析:真正的Log4j的初始化和關閉真正的執行者Log4jConfigurer,Log4jWebConfigurer只是Log4j在