Struts2 log principle and configuration method

Struts2 does not use Log4j, JCL (Apache Java Commons Logger) or slf4j directly.

It writes its own LoggerFactory (com.opensymphony.xwork2.util.logging.LoggerFactory), then lets it choose which LoggerFactory to use before logging.

 

For use in actions, it can be coded as follows:

 

private Logger logger = LoggerFactory.getLogger(FooAction.class);

String msg="debug level logger Info";
logger.debug(msg);

 

The log source code in struts2 involves:

 

In the init method of the org.apache.struts2.dispatcher.ng.filter.StrutsPrepareAndExecuteFilter class, initialize the log object as follows:

 

public void init(FilterConfig filterConfig) throws ServletException {
        InitOperations init = new InitOperations();
        Dispatcher dispatcher = null;
        try {
            FilterHostConfig config = new FilterHostConfig(filterConfig);
            init.initLogging(config);
            dispatcher = init.initDispatcher(config);
            init.initStaticContentLoader(config, dispatcher);

            prepare = new PrepareOperations(filterConfig.getServletContext(), dispatcher);
            execute = new ExecuteOperations(filterConfig.getServletContext(), dispatcher);
            this.excludedPatterns = init.buildExcludedPatternsList(dispatcher);

            postInit(dispatcher, filterConfig);
        } finally {
            if (dispatcher != null) {
                dispatcher.cleanUpAfterInit();
            }
            init.cleanup();
        }
    }

 

The initLogging method in the org.apache.struts2.dispatcher.ng.InitOperations class,

 

public void initLogging( HostConfig filterConfig ) {
        String factoryName = filterConfig.getInitParameter("loggerFactory");
        if (factoryName != null) {
            try {
                Class cls = ClassLoaderUtil.loadClass(factoryName, this.getClass());
                LoggerFactory fac = (LoggerFactory) cls.newInstance();
                LoggerFactory.setLoggerFactory(fac);
            } catch ( InstantiationException e ) {
                System.err.println("Unable to instantiate logger factory: " + factoryName + ", using default");
                e.printStackTrace ();
            } catch ( IllegalAccessException e ) {
                System.err.println("Unable to access logger factory: " + factoryName + ", using default");
                e.printStackTrace ();
            } catch ( ClassNotFoundException e ) {
                System.err.println("Unable to locate logger factory class: " + factoryName + ", using default");
                e.printStackTrace ();
            }
        }
    }

 

The following code shows that Struts will load the LoggerFactory through a parameter named loggerFactory,
which can be set by setting
<filter>
<filter-name>strut2</filter-name>
<filter-class>
org.apache.struts2 in web.xml. dispatcher.ng.filter.StrutsPrepareAndExecuteFilter
</filter-class>
<init-param>
<param-name>loggerFactory</param-name>
<param-value>
com.opensymphony.xwork2.util.logging.commons.CommonsLoggerFactory
</ param-value>
</init-param>
</filter>

 

Let's take a look at the implementation of the LoggerFactory.getLogger(); method

 

See com.opensymphony.xwork2.util.logging.LoggerFactory class.

 

public static void setLoggerFactory(LoggerFactory factory) {
        lock.writeLock().lock();
        try {
            LoggerFactory.factory = factory;
        } finally {
            lock.writeLock().unlock();
        }

    }

 Set the log processing class, where write lock processing is used.

 

 

 

 

public static Logger getLogger(String name) {
        return getLoggerFactory().getLoggerImpl(name);
    }

 

protected static LoggerFactory getLoggerFactory() {
        lock.readLock().lock();
        try {
            if (factory != null) {
                return factory;
            }
        } finally {
            lock.readLock().unlock();
        }
        lock.writeLock().lock();
        try {
            if (factory == null) {
                String userLoggerFactory = System.getProperty(XWorkConstants.XWORK_LOGGER_FACTORY);
                if (userLoggerFactory != null) {
                    try {
                        Class clazz = Class.forName(userLoggerFactory);
                        factory = (LoggerFactory) clazz.newInstance();
                    } catch (Exception e) {
                        throw new XWorkException("System property [" + XWorkConstants.XWORK_LOGGER_FACTORY +
                                "] was defined as [" + userLoggerFactory + "] but there is a problem to use that LoggerFactory!", e);
                    }
                } else {
                    try {
                        Class.forName("org.apache.commons.logging.LogFactory");
                        factory = new com.opensymphony.xwork2.util.logging.commons.CommonsLoggerFactory();
                    } catch (ClassNotFoundException ex) {
                        //commons-logging not found try slf4j LogFactory
                        try {
                            Class.forName("org.slf4j.LoggerFactory");
                            factory = new Slf4jLoggerFactory();
                        } catch (ClassNotFoundException cnfex) {
                            // slf4j not found, falling back to jdk logging
                            factory = new JdkLoggerFactory();
                        }
                    }
                }
            }
            return factory;
        } finally {
            lock.writeLock().unlock();
        }
    }

  

The log acquisition class has been fetched four times in total.

1. Read the configuration file of the webwork

2,org.apache.commons.logging.LogFactory
3,org.slf4j.LoggerFactory
4,JdkLoggerFactory

 

Guess you like

Origin http://10.200.1.11:23101/article/api/json?id=326701368&siteId=291194637