slf4j - 门面模式 - 架构分析

所谓门面模式:提供一个统一接口给用户去访问多个子系统的多个不同接口;

优点:

1.子系统之间解耦

2.简化用户对子系统的使用

3.子系统易扩展增加

缺点:

子系统实现与客户程序存在很大依赖性,需预制客户程序的功能

下以slf4j 为例分析其门面模式实现原理

1. 门面架构分析

    

2. 源码实现分析

  1>  用户通过 Logger logger = LoggerFactory.getLogger(TestMain.class) 获取Logger实例

  2> slf4j 通过门面类LoggerFactory查找子系统的实现,可以debug 跟踪 slf4j 源码

    public static Logger getLogger(String name) {
        ILoggerFactory iLoggerFactory = getILoggerFactory();
        return iLoggerFactory.getLogger(name);
    }

  3> 通过实例类路径"org/slf4j/impl/StaticLoggerBinder.class" 查找加载实现类StaticLoggerBinder(发现多个子系统实现则由JVM选择加载实现类), 通过单例获取子系统实现类LoggerFactory ,未找到实现类则加载NOP类,修改初始化状态。

   private final static void bind() {
        try {
            Set<URL> staticLoggerBinderPathSet = null;
            // skip check under android, see also
            // http://jira.qos.ch/browse/SLF4J-328
            if (!isAndroid()) {
                staticLoggerBinderPathSet = findPossibleStaticLoggerBinderPathSet();
                reportMultipleBindingAmbiguity(staticLoggerBinderPathSet);
            }
            // the next line does the binding
            StaticLoggerBinder.getSingleton();
            INITIALIZATION_STATE = SUCCESSFUL_INITIALIZATION;
            reportActualBinding(staticLoggerBinderPathSet);
            fixSubstituteLoggers();
            replayEvents();
            // release all resources in SUBST_FACTORY
            SUBST_FACTORY.clear();
        } 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.contains("org.slf4j.impl.StaticLoggerBinder.getSingleton()")) {
                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);
        }
    }

  4> 至此完成绑定子系统日志实现框架

后续会更新 slf4j + logback 实现方式及部分源码分析

猜你喜欢

转载自www.cnblogs.com/neverm-one/p/9728192.html