看了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)); } ... }