类图
前面代码看出来 最终返回的是LoggerContext这个类实现了LogFactory
成员变量
//表示根logger final Logger root = new Logger("ROOT", (Logger)null, this); //标识创建了多少个logger private int size; //未知 private int noAppenderWarning = 0; //<1>接口的实例能监听 logger context 上发生的事件,比如说日志级别的变化 private final List<LoggerContextListener> loggerContextListenerList = new ArrayList(); //logger缓存 get一次会存入缓存同时size++下次直接从缓存拿 private Map<String, Logger> loggerCache = new ConcurrentHashMap(); //loggerContextVO对象 private LoggerContextVO loggerContextRemoteView = new LoggerContextVO(this); private final TurboFilterList turboFilterList = new TurboFilterList(); private boolean packagingDataEnabled = false; private int maxCallerDataDepth = 8; //记录LoggerContext调用了几次方法 int resetCount = 0; private List<String> frameworkPackages;
<1>配置方式
<?xml version="1.0" encoding="UTF-8" ?> <configuration debug="true" scan="true" scanPeriod="60 seconds"> <contextListener class="com.midea.jr.credit.accounting.utils.LoggerStartupListener" /> </configuration>
LoggerFactory
getILoggerFactory
摘自:《logback源码阅读-集成slf4j初始化过程(一)》
复制代码 public static ILoggerFactory getILoggerFactory() { /** * 0:未初始化 * 1:准备初始化 * 2:类没有实现LoggerFactoryBinder 相关方法 * 3:获取binder成功 * 4:没有找到相关类 */ static volatile int INITIALIZATION_STATE = 0; //这个工厂创建NOPLogger实例 是个空实现 static final NOPLoggerFactory NOP_FALLBACK_FACTORY = new NOPLoggerFactory(); public static ILoggerFactory getILoggerFactory() { /** * 判断是否初始化 */ if (INITIALIZATION_STATE == 0) { Class var0 = LoggerFactory.class; //加锁并判断 防止初始化后释放锁 等待的进来重复加载 synchronized(LoggerFactory.class) { if (INITIALIZATION_STATE == 0) { //标识正在初始化 INITIALIZATION_STATE = 1; //<4>执行初始化化绑定 performInitialization(); } } } switch(INITIALIZATION_STATE) { case 1: return SUBST_FACTORY; case 2: throw new IllegalStateException("org.slf4j.LoggerFactory in failed state. Original exception was thrown EARLIER. See also http://www.slf4j.org/codes.html#unsuccessfulInit"); case 3: //<1>可以看到此处是根据StaticLoggerBinder 这是一个slf4j继承点 为logback实现 下面会讲 return StaticLoggerBinder.getSingleton().getLoggerFactory(); case 4: return NOP_FALLBACK_FACTORY; default: throw new IllegalStateException("Unreachable code"); } } }
StaticLoggerBinder
<1>getLoggerFactory
org.slf4j.impl.StaticLoggerBinder#getILoggerFactory
private LoggerContext defaultLoggerContext = new LoggerContext(); public ILoggerFactory getLoggerFactory() { if (!this.initialized) { return this.defaultLoggerContext; } else if (this.contextSelectorBinder.getContextSelector() == null) { throw new IllegalStateException("contextSelector cannot be null. See also http://logback.qos.ch/codes.html#null_CS"); } else { return this.contextSelectorBinder.getContextSelector().getLoggerContext(); } }
LoggerContext
getLogger
ch.qos.logback.classic.LoggerContext#getLogger(java.lang.String)
public final Logger getLogger(String name) { //如果name为空抛出异常 正常不会出现 if (name == null) { throw new IllegalArgumentException("name argument cannot be null"); //如果传入的是root直接返回root Logger } else if ("ROOT".equalsIgnoreCase(name)) { return this.root; } else { int i = 0; Logger logger = this.root; //从缓存中获取Logger如果没有则 Logger childLogger = (Logger)this.loggerCache.get(name); if (childLogger != null) { return childLogger; } else { int h; do { //<1>这里根据,号分割依次连续截取 h = LoggerNameUtil.getSeparatorIndexOf(name, i); String childName; if (h == -1) { childName = name; } else { childName = name.substring(0, h); } i = h + 1; synchronized(logger) { //<2>会维护父子关系 childLogger = logger.getChildByName(childName); if (childLogger == null) { childLogger = logger.createChildByName(childName); this.loggerCache.put(childName, childLogger); //每次创建count++ this.incSize(); } } logger = childLogger; } while(h != -1); return childLogger; } } }
<1>处会依次截取创建logger并放入cache 同时维护父子关系
cache数据
来源:https://www.cnblogs.com/LQBlog/p/12161079.html