“SLF4J 日志绑定原理”的版本间的差异
		
		
		
		
		
		跳到导航
		跳到搜索
		
				
		
		
	
Jihongchang(讨论 | 贡献)  (建立内容为“https://www.bilibili.com/video/BV1iJ411H74S?p=24”的新页面)  | 
				Jihongchang(讨论 | 贡献)   | 
				||
| 第1行: | 第1行: | ||
https://www.bilibili.com/video/BV1iJ411H74S?p=24  | https://www.bilibili.com/video/BV1iJ411H74S?p=24  | ||
| + | |||
| + | === 源码跟踪 ===  | ||
| + | |||
| + | ==== SLF4JTest.java ====  | ||
| + | <syntaxhighlight lang="java">  | ||
| + | ……  | ||
| + | public class SLF4JTest {  | ||
| + | |||
| + |     public static final Logger LOGGER = LoggerFactory.getLogger(SLF4JTest.class);  | ||
| + |     ……  | ||
| + | }  | ||
| + | </syntaxhighlight>  | ||
| + | |||
| + | ==== LoggerFactory.java ====  | ||
| + | <syntaxhighlight lang="java">  | ||
| + | ……  | ||
| + | public final class LoggerFactory {  | ||
| + | |||
| + |     ……  | ||
| + |     public static Logger getLogger(String name) {  | ||
| + |         ILoggerFactory iLoggerFactory = getILoggerFactory();  | ||
| + |         return iLoggerFactory.getLogger(name);  | ||
| + |     }  | ||
| + |     public static Logger getLogger(Class<?> clazz) {  | ||
| + |         Logger logger = getLogger(clazz.getName());  | ||
| + |         if (DETECT_LOGGER_NAME_MISMATCH) {  | ||
| + |             Class<?> autoComputedCallingClass = Util.getCallingClass();  | ||
| + |             if (autoComputedCallingClass != null && nonMatchingClasses(clazz, autoComputedCallingClass)) {  | ||
| + |                 Util.report(String.format("Detected logger name mismatch. Given name: \"%s\"; computed name: \"%s\".", logger.getName(), autoComputedCallingClass.getName()));  | ||
| + |                 Util.report("See http://www.slf4j.org/codes.html#loggerNameMismatch for an explanation");  | ||
| + |             }  | ||
| + |         }  | ||
| + | |||
| + |         return logger;  | ||
| + |     }  | ||
| + |     ……  | ||
| + |     public static ILoggerFactory getILoggerFactory() {  | ||
| + |         if (INITIALIZATION_STATE == 0) {  | ||
| + |             Class var0 = LoggerFactory.class;  | ||
| + |             synchronized(LoggerFactory.class) {  | ||
| + |                 if (INITIALIZATION_STATE == 0) {  | ||
| + |                     INITIALIZATION_STATE = 1;  | ||
| + |                     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:  | ||
| + |                 return StaticLoggerBinder.getSingleton().getLoggerFactory();  | ||
| + |             case 4:  | ||
| + |                 return NOP_FALLBACK_FACTORY;  | ||
| + |             default:  | ||
| + |                 throw new IllegalStateException("Unreachable code");  | ||
| + |         }  | ||
| + |     }  | ||
| + |     ……  | ||
| + |     private static final void performInitialization() {  | ||
| + |         bind();  | ||
| + |         if (INITIALIZATION_STATE == 3) {  | ||
| + |             versionSanityCheck();  | ||
| + |         }  | ||
| + | |||
| + |     }  | ||
| + |     ……  | ||
| + |     private static final void bind() {  | ||
| + |         String msg;  | ||
| + |         try {  | ||
| + |             Set<URL> staticLoggerBinderPathSet = null;  | ||
| + |             if (!isAndroid()) {  | ||
| + |                 staticLoggerBinderPathSet = findPossibleStaticLoggerBinderPathSet();  | ||
| + |                 reportMultipleBindingAmbiguity(staticLoggerBinderPathSet);  | ||
| + |             }  | ||
| + | |||
| + |             StaticLoggerBinder.getSingleton();  | ||
| + |             INITIALIZATION_STATE = 3;  | ||
| + |             reportActualBinding(staticLoggerBinderPathSet);  | ||
| + |             fixSubstituteLoggers();  | ||
| + |             replayEvents();  | ||
| + |             SUBST_FACTORY.clear();  | ||
| + |         } catch (NoClassDefFoundError var2) {  | ||
| + |             msg = var2.getMessage();  | ||
| + |             if (!messageContainsOrgSlf4jImplStaticLoggerBinder(msg)) {  | ||
| + |                 failedBinding(var2);  | ||
| + |                 throw var2;  | ||
| + |             }  | ||
| + | |||
| + |             INITIALIZATION_STATE = 4;  | ||
| + |             Util.report("Failed to load class \"org.slf4j.impl.StaticLoggerBinder\".");  | ||
| + |             Util.report("Defaulting to no-operation (NOP) logger implementation");  | ||
| + |             Util.report("See http://www.slf4j.org/codes.html#StaticLoggerBinder for further details.");  | ||
| + |         } catch (NoSuchMethodError var3) {  | ||
| + |             msg = var3.getMessage();  | ||
| + |             if (msg != null && msg.contains("org.slf4j.impl.StaticLoggerBinder.getSingleton()")) {  | ||
| + |                 INITIALIZATION_STATE = 2;  | ||
| + |                 Util.report("slf4j-api 1.6.x (or later) is incompatible with this binding.");  | ||
| + |                 Util.report("Your binding is version 1.5.5 or earlier.");  | ||
| + |                 Util.report("Upgrade your binding to version 1.6.x.");  | ||
| + |             }  | ||
| + | |||
| + |             throw var3;  | ||
| + |         } catch (Exception var4) {  | ||
| + |             failedBinding(var4);  | ||
| + |             throw new IllegalStateException("Unexpected initialization failure", var4);  | ||
| + |         }  | ||
| + | |||
| + |     }  | ||
| + |     ……  | ||
| + | }  | ||
| + | </syntaxhighlight>调用顺序:LoggerFactory.getLogger(Class<?> clazz)  | ||
| + | |||
| + | -> LoggerFactory.getLogger(String name)  | ||
| + | |||
| + | -> LoggerFactory.getILoggerFactory()  | ||
| + | |||
| + | -> LoggerFactory.performInitialization()  | ||
| + | |||
| + | -> LoggerFactory.bind()  | ||
2023年2月26日 (日) 13:41的版本
https://www.bilibili.com/video/BV1iJ411H74S?p=24
源码跟踪
SLF4JTest.java
……
public class SLF4JTest {
    public static final Logger LOGGER = LoggerFactory.getLogger(SLF4JTest.class);
    ……
}
LoggerFactory.java
……
public final class LoggerFactory {
    ……
    public static Logger getLogger(String name) {
        ILoggerFactory iLoggerFactory = getILoggerFactory();
        return iLoggerFactory.getLogger(name);
    }
    public static Logger getLogger(Class<?> clazz) {
        Logger logger = getLogger(clazz.getName());
        if (DETECT_LOGGER_NAME_MISMATCH) {
            Class<?> autoComputedCallingClass = Util.getCallingClass();
            if (autoComputedCallingClass != null && nonMatchingClasses(clazz, autoComputedCallingClass)) {
                Util.report(String.format("Detected logger name mismatch. Given name: \"%s\"; computed name: \"%s\".", logger.getName(), autoComputedCallingClass.getName()));
                Util.report("See http://www.slf4j.org/codes.html#loggerNameMismatch for an explanation");
            }
        }
        return logger;
    }
    ……
    public static ILoggerFactory getILoggerFactory() {
        if (INITIALIZATION_STATE == 0) {
            Class var0 = LoggerFactory.class;
            synchronized(LoggerFactory.class) {
                if (INITIALIZATION_STATE == 0) {
                    INITIALIZATION_STATE = 1;
                    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:
                return StaticLoggerBinder.getSingleton().getLoggerFactory();
            case 4:
                return NOP_FALLBACK_FACTORY;
            default:
                throw new IllegalStateException("Unreachable code");
        }
    }
    ……
    private static final void performInitialization() {
        bind();
        if (INITIALIZATION_STATE == 3) {
            versionSanityCheck();
        }
    }
    ……
    private static final void bind() {
        String msg;
        try {
            Set<URL> staticLoggerBinderPathSet = null;
            if (!isAndroid()) {
                staticLoggerBinderPathSet = findPossibleStaticLoggerBinderPathSet();
                reportMultipleBindingAmbiguity(staticLoggerBinderPathSet);
            }
            StaticLoggerBinder.getSingleton();
            INITIALIZATION_STATE = 3;
            reportActualBinding(staticLoggerBinderPathSet);
            fixSubstituteLoggers();
            replayEvents();
            SUBST_FACTORY.clear();
        } catch (NoClassDefFoundError var2) {
            msg = var2.getMessage();
            if (!messageContainsOrgSlf4jImplStaticLoggerBinder(msg)) {
                failedBinding(var2);
                throw var2;
            }
            INITIALIZATION_STATE = 4;
            Util.report("Failed to load class \"org.slf4j.impl.StaticLoggerBinder\".");
            Util.report("Defaulting to no-operation (NOP) logger implementation");
            Util.report("See http://www.slf4j.org/codes.html#StaticLoggerBinder for further details.");
        } catch (NoSuchMethodError var3) {
            msg = var3.getMessage();
            if (msg != null && msg.contains("org.slf4j.impl.StaticLoggerBinder.getSingleton()")) {
                INITIALIZATION_STATE = 2;
                Util.report("slf4j-api 1.6.x (or later) is incompatible with this binding.");
                Util.report("Your binding is version 1.5.5 or earlier.");
                Util.report("Upgrade your binding to version 1.6.x.");
            }
            throw var3;
        } catch (Exception var4) {
            failedBinding(var4);
            throw new IllegalStateException("Unexpected initialization failure", var4);
        }
    }
    ……
}
调用顺序:LoggerFactory.getLogger(Class<?> clazz)
-> LoggerFactory.getLogger(String name)
-> LoggerFactory.getILoggerFactory()
-> LoggerFactory.performInitialization()
-> LoggerFactory.bind()