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

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);

    }

  }

到此,就真正拿到实现类的实例了

slf自己主动绑定实现类过程推断的更多相关文章

  1. Cocos2d-x JSB 自己主动绑定bindings

    Javascript Binding (简称JSB) 自己主动绑定教程. Cocos2d-x JSB 自己主动绑定bindings-generator (以下简称B-G) 使用心得 假设想弄清深入原理 ...

  2. cocos2dx 自己主动绑定js

    依照教程把全部资源下载好后....... 找到cocos2dx project下的tools/bindings-generator/test 发现里面有test.sh , test.ini , 去掉s ...

  3. Spring绑定请求参数过程以及使用@InitBinder来注册自己的属性处理器

    在工作中,经常会出现前台的请求参数由于无法被正常转型,导致请求无法进到后台的问题. 比如,我有一个User.其性别的属性被定义成了枚举,如下: public enum Gender { MALE(&q ...

  4. cocos2dx lua 绑定之二:手动绑定自定义类中的函数

    cococs2dx 3.13.1 + vs2013 + win10 1.首先按照<cocos2dx lua 绑定之一:自动绑定自定义类>绑定Student类 2.在Student类中增加一 ...

  5. cocos2dx 2.x版本:简化提炼tolua++绑定自定义类到lua中使用

    cocos2dx的3.x版本已经提供了更好地绑定方式,网上有很多相关的教程,这里给一个链接:http://www.cocoachina.com/bbs/read.php?tid=196416. 由于目 ...

  6. WPF——传实体类及绑定实体类属性

    public class User: private string _User; public string User1 { get { return _User; } set { _User = v ...

  7. silverlight datagrid绑定匿名类

    原文 http://www.cnblogs.com/luweis/archive/2011/10/21/2220587.html 刚开始遇到的一个问题是这样的,我有一个datagrid,根据不同的条件 ...

  8. 使用MethodType函数将方法绑定到类或实例上

    在开始正文之前,需要了解下Python的绑定方法(bound method)和非绑定方法. 简单做个测试: 定义一个类,类中由实例方法.静态方法和类方法. class ClassA: def inst ...

  9. cocos2dx lua 绑定之一:自动绑定自定义类中的函数

    cococs2dx 3.13.1 + vs2013 + win10 1.首先定义C++类Student 在cocos2d-x\cocos文件夹下新建一个user_define的文件夹放置两个文件. 注 ...

随机推荐

  1. JS中 document.getElementById 对象

    Document 对象 每个载入浏览器的 HTML 文档都会成为 Document 对象. Document 对象使我们可以从脚本中对 HTML 页面中的所有元素进行访问. 提示:Document 对 ...

  2. Wake-On-LAN待机或休眠模式中唤醒

    Wake-On-LAN简称WOL,是一种电源管理功能:如果存在网络活动,则允许设备将操作系统从待机或休眠模式中唤醒.许多主板厂商支持IBM提出的网络唤醒标准.该标准允许网络管理员远程打开PC机电源,以 ...

  3. 基于MVC3下拉列表联动(JQuery)

    上次项目中遇到一个需要多个下拉列表联动的操作,今天有空将实现方式整理以便以后参考. 要达到的效果是,点击一个下拉框,则另一个下拉框的值发生对应变化.如:选择中国,则另个一下拉框里显示中国各个省份. 传 ...

  4. uva11600 状压期望dp

    一般的期望dp是, dp[i] = dp[j] * p[j] + 1; 即走到下一步需要1的时间,然后加上 下一步走到目标的期望*这一步走到下一步的概率 这一题,我们将联通分块缩为一个点,因为联通块都 ...

  5. Big Event in HDU(杭电1171)(多重背包)和(母函数)两种解法

    Big Event in HDU Time Limit: 10000/5000 MS (Java/Others)    Memory Limit: 65536/32768 K (Java/Others ...

  6. Android 纯代码加入点击效果

    项目中非常多的Button, 同一时候配置非常多button切图,Selector是不是非常烦, 使用以下这个类,就能够直接为Button添加点击效果. 不用多个图片,不用Selector. 使用方法 ...

  7. 什么是IT

    这个是同事总结的,我补充了若干项,算不上原创,但这个没有在其他地方看到,在这儿权且当原创了.后面再配个软件架构图吧.看到缺的同学能够补充 什么是IT:Information-信息Technology- ...

  8. android一些面试题目

    1.ListView怎么提高滑动效率 2.说下你做过项目的包的构架,(联网,解析,activity,database) 重点 3.载入大量图片怎么做(包含小图和查看大图) 怎么降低一次跟server的 ...

  9. 设计模式——辛格尔顿(Singleton)

    要想正确理解设计模式,首先必须明白它是为了解决什么问题而提出来的. 设计模式学习笔记 --Shulin 转载请注明出处:http://blog.csdn.net/zhshulin 单例模式属于设计模式 ...

  10. Python多线程的threading Event

    Python threading模块提供Event对象用于线程间通信.它提供了一组.拆除.等待用于线程间通信的其他方法. event它是沟通中最简单的一个过程之中,一个线程产生一个信号,号.Pytho ...