zoukankan      html  css  js  c++  java
  • slf自己主动绑定实现类过程推断

    依照绑定实现类的方式是基于约定原则:推断分下面几个步骤

    1.LoggerFactory扫描实现类路径有几个实现类,即在org/slf4j/impl/下有几个StaticLoggerBinder.class
    2.假设有多个实现类,向开发者报告多个实现类的路径
    3.假设有多个实现类,向开发者报告真正绑定的是哪一个实现类
    4.假设没有实现类,怎么办?

    详细代码实现

    //要扫描的文件路径 
      private static String STATIC_LOGGER_BINDER_PATH = "org/slf4j/impl/StaticLoggerBinder.class";

    //扫描全部的StaticLoggerBinder.class路径放入到set集合
      private static Set findPossibleStaticLoggerBinderPathSet() {
        // use Set instead of list in order to deal with  bug #138
        // LinkedHashSet appropriate here because it preserves insertion order during iteration
        Set staticLoggerBinderPathSet = new LinkedHashSet();
        try {
          ClassLoader loggerFactoryClassLoader = LoggerFactory.class
                  .getClassLoader();
          Enumeration paths;
          if (loggerFactoryClassLoader == null) {
            paths = ClassLoader.getSystemResources(STATIC_LOGGER_BINDER_PATH);
          } else {
            paths = loggerFactoryClassLoader
                    .getResources(STATIC_LOGGER_BINDER_PATH);
          }
          while (paths.hasMoreElements()) {
            URL path = (URL) paths.nextElement();
            staticLoggerBinderPathSet.add(path);
          }
        } catch (IOException ioe) {
          Util.report("Error getting resources from path", ioe);
        }
        return staticLoggerBinderPathSet;
      }

    //报告全部的实现类路径
      private static void reportMultipleBindingAmbiguity(Set staticLoggerBinderPathSet) {
        if (isAmbiguousStaticLoggerBinderPathSet(staticLoggerBinderPathSet)) {
          Util.report("Class path contains multiple SLF4J bindings.");
          Iterator iterator = staticLoggerBinderPathSet.iterator();
          while (iterator.hasNext()) {
            URL path = (URL) iterator.next();
            Util.report("Found binding in [" + path + "]");
          }
          Util.report("See " + MULTIPLE_BINDINGS_URL + " for an explanation.");
        }
      }

    //报告真正用到的实现类名称
    private static void reportActualBinding(Set staticLoggerBinderPathSet) {
        if (isAmbiguousStaticLoggerBinderPathSet(staticLoggerBinderPathSet)) {
          Util.report("Actual binding is of type ["+StaticLoggerBinder.getSingleton().getLoggerFactoryClassStr()+"]");
        }
      }



    //去拿到实现类的实例,由于StaticLoggerBinder类不一定存在,所以要捕获NoClassDefFoundError异常

    private final static void bind() {
        try {
          Set staticLoggerBinderPathSet = findPossibleStaticLoggerBinderPathSet();
          reportMultipleBindingAmbiguity(staticLoggerBinderPathSet);
          // the next line does the binding
          StaticLoggerBinder.getSingleton();
          INITIALIZATION_STATE = SUCCESSFUL_INITIALIZATION;
          reportActualBinding(staticLoggerBinderPathSet);
          emitSubstituteLoggerWarning();
        } catch (NoClassDefFoundError ncde) {
          String msg = ncde.getMessage();
          if (messageContainsOrgSlf4jImplStaticLoggerBinder(msg)) {
            INITIALIZATION_STATE = NOP_FALLBACK_INITIALIZATION;
            Util.report("Failed to load class "org.slf4j.impl.StaticLoggerBinder".");
            Util.report("Defaulting to no-operation (NOP) logger implementation");
            Util.report("See " + NO_STATICLOGGERBINDER_URL
                    + " for further details.");
          } else {
            failedBinding(ncde);
            throw ncde;
          }
        } catch (java.lang.NoSuchMethodError nsme) {
          String msg = nsme.getMessage();
          if (msg != null && msg.indexOf("org.slf4j.impl.StaticLoggerBinder.getSingleton()") != -1) {
            INITIALIZATION_STATE = FAILED_INITIALIZATION;
            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 nsme;
        } catch (Exception e) {
          failedBinding(e);
          throw new IllegalStateException("Unexpected initialization failure", e);
        }
      }

    到此,就真正拿到实现类的实例了
  • 相关阅读:
    [Python自学] PyQT5-Web控件、与JavaScript交互
    [Python自学] PyQT5-选项卡窗口、堆栈窗口、停靠窗口、子窗口
    [Python自学] PyQT5-窗口风格、窗口样式、GIF动画、窗口透明
    [Python自学] PyQT5-子线程更新UI数据、信号槽自动绑定、lambda传参、partial传参、覆盖槽函数
    [Python自学] PyQT5-信号与槽
    [Python自学] PyQT5-菜单栏、工具栏、状态栏
    [Python自学] PyQT5-控件拖拽、剪切板
    [Python自学] PyQT5-各种QDialog对话框
    [Python自学] PyQT5-QSpinBox、QSlider控件
    Linux操作系统分析 | 课程学习总结报告
  • 原文地址:https://www.cnblogs.com/mfrbuaa/p/4049143.html
Copyright © 2011-2022 走看看