看了STRUTS2的源码,了解了它的logging系统,觉得还是蛮有意思的,用到了很多设计模式。
先看类结构图:
1. 工厂方法模式
这个就不说了,直接明了。
2. 伪单例模式
LoggerFactory是个抽象方法,同时里面也包含了对于LoggerFactory的伪单例实现。为什么是伪单例,因为看起来像是单例模式,但其实你也可以创建多个实例:
public static void setLoggerFactory(LoggerFactory factory) {
lock.writeLock().lock();
try {
LoggerFactory.factory = factory;
} finally {
lock.writeLock().unlock();
}
}
protected static LoggerFactory getLoggerFactory() {
lock.readLock().lock();
try {
if (factory != null) {
return factory;
}
} finally {
lock.readLock().unlock();
}
lock.writeLock().lock();
try {
if (factory == null) {
try {
Class.forName("org.apache.commons.logging.LogFactory");
factory = new com.opensymphony.xwork2.util.logging.commons.CommonsLoggerFactory();
} catch (ClassNotFoundException ex) {
// commons logging not found, falling back to jdk logging
factory = new JdkLoggerFactory();
}
}
return factory;
}
finally {
lock.writeLock().unlock();
}
}
这里还用到了concurrent包里面的ReentrantReadWriteLock锁,看着使用方法貌似还蛮简单的,以后可以将这个类放到工具箱里。
3. 模板方法模式
LoggerFactory:
public static Logger getLogger(Class<?> cls) {
return getLoggerFactory().getLoggerImpl(cls);
}
public static Logger getLogger(String name) {
return getLoggerFactory().getLoggerImpl(name);
}
protected abstract Logger getLoggerImpl(Class<?> cls);
protected abstract Logger getLoggerImpl(String name);
JdkLoggerFactory:
public class JdkLoggerFactory extends LoggerFactory {
@Override
protected Logger getLoggerImpl(Class<?> cls) {
return new JdkLogger(java.util.logging.Logger.getLogger(cls.getName()));
}
@Override
protected Logger getLoggerImpl(String name) {
return new JdkLogger(java.util.logging.Logger.getLogger(name));
}
}
4. 代理模式
JDKLogger并没有做任何事情,而是直接代理给了java.util.logging.Logger类:
public class JdkLogger implements Logger {
private java.util.logging.Logger log;
public JdkLogger(java.util.logging.Logger log) {
this.log = log;
}
public void error(String msg, String... args) {
log.log(Level.SEVERE, LoggerUtils.format(msg, args));
}
...
}