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数据

  • 相关阅读:
    cocos2d-x 配置教程
    cocos2d-x 学习笔记之 CCMenuItemToggle用法
    cocos2d-android-1学习之旅01
    博客园的代码高亮
    JAVA POI 应用系列(2)--读取Excel
    JAVA POI 应用系列(1)--生成Excel
    spring和hibernate的整合
    学习笔记
    mongorestore 命令行恢复 bson
    mysql 插数据 ,版本不一致 需要修改 utf8 COLLATE utf8_general_ci
  • 原文地址:https://www.cnblogs.com/LQBlog/p/12161079.html
Copyright © 2011-2022 走看看