zoukankan      html  css  js  c++  java
  • logback源码阅读-获取Logger(二)

    类图

    前面代码看出来 最终返回的是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数据

  • 相关阅读:
    LeetCode 100. 相同的树(Same Tree) 2
    LeetCode 680. 验证回文字符串 Ⅱ(Valid Palindrome II) 1
    MySQL索引操作
    MySQL数据库的一些方法使用
    Anaconda安装新模块
    源码下载
    mongodb内建角色
    windows server 2008开启共享文件设置
    MySQL配置说明
    MySQL的连接数
  • 原文地址:https://www.cnblogs.com/LQBlog/p/12161079.html
Copyright © 2011-2022 走看看