Struts2没有直接使用Log4j、JCL(Apache Java Commons Logger)或slf4j。
它编写了自己的LoggerFactory(com.opensymphony.xwork2.util.logging.LoggerFactory),然后让其选择使用何种LoggerFactory,然后再进行日志处理。
在action中使用,可以按照以下的方式编码:
private Logger logger = LoggerFactory.getLogger(FooAction.class);
String msg="debug level logger Info";
logger.debug(msg);
struts2中日志源码涉及的有:
在org.apache.struts2.dispatcher.ng.filter.StrutsPrepareAndExecuteFilter类中init方法中,初始化日志对象,如下:
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();
}
}
在org.apache.struts2.dispatcher.ng.InitOperations类中的initLogging方法,
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();
}
}
}
以下代码显示,Struts会通过名为loggerFactory的参数加载LoggerFactory,
则可以通过在web.xml中设置
<filter>
<filter-name>strut2</filter-name>
<filter-class>
org.apache.struts2.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>
以下看看LoggerFactory.getLogger();方法的实现
见com.opensymphony.xwork2.util.logging.LoggerFactory类。
public static void setLoggerFactory(LoggerFactory factory) {
lock.writeLock().lock();
try {
LoggerFactory.factory = factory;
} finally {
lock.writeLock().unlock();
}
}
设置日志处理类,此处用到了写锁处理。
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();
}
}
日志获取类共取了四次,
1,webwork的配置文件读取
2,org.apache.commons.logging.LogFactory
3,org.slf4j.LoggerFactory
4,JdkLoggerFactory