slf4j-log4j2的初始化流程

一、动态绑定和静态绑定
  1. 动态绑定:在运行时才能确定加载哪个对象,往往通过配置文件的方式来加载。类似如下代码
String factoryClass = props.getProperty("org.apache.commons.logging.LogFactory");
Class logFactoryClass = classLoader.loadClass(factoryClass);
logFactoryClass.newInstance();
  1. 静态绑定:编译的时候就确定了某个对象,简单点说就是你开发的时候直接使用了某个对象。类似如下代码
import org.slf4j.impl.StaticLoggerBinder;
public class Test3 {
    public static void main(String[] args) {
       new StaticLoggerBinder();
    }
}

假如StaticLoggerBinder在另一个包B,然后你打包了Test3为A,然后把A用在另一个项目C。此时你必须引入B才能正常使用,这种A对B的依赖就是静态绑定。

  1. 总结:动态绑定具体使用哪个对象是不确定的,只要实现了org.apache.commons.logging.LogFactory接口就行,他可能是com.test.A.class或者com.dd.aa.B.class 等等。静态绑定则已经确定了必须是org.slf4j.impl.StaticLoggerBinder,其他的对象都不可以。
二、slf4j-log4j2的初始化流程
Logger logger = LoggerFactory.getLogger(getClass());

初始化由LoggerFactory.getLogger方法触发。相关代码如下

public final class LoggerFactory {

   public static Logger getLogger(String name) {
        /**
        这里需要获取实现了ILoggerFactory接口的对象
        */
        ILoggerFactory iLoggerFactory = getILoggerFactory();
        return iLoggerFactory.getLogger(name);
    }
    
    public static ILoggerFactory getILoggerFactory() {
        if (INITIALIZATION_STATE == UNINITIALIZED) {
            synchronized (LoggerFactory.class) {
                if (INITIALIZATION_STATE == UNINITIALIZED) {
                    INITIALIZATION_STATE = ONGOING_INITIALIZATION;
                    //这里进行绑定,会调用bind()方法
                    performInitialization();
                }
            }
        }
        switch (INITIALIZATION_STATE) {
        case SUCCESSFUL_INITIALIZATION:
           /**
           最终会走到这里,StaticLoggerBinder是桥接包log4j-slf4j-impl-*.jar中的对象,getLoggerFactory()返回了Log4jLoggerFactory对象
           */
            return StaticLoggerBinder.getSingleton().getLoggerFactory();
        case NOP_FALLBACK_INITIALIZATION:
            return NOP_FALLBACK_FACTORY;
        case FAILED_INITIALIZATION:
            throw new IllegalStateException(UNSUCCESSFUL_INIT_MSG);
        case ONGOING_INITIALIZATION:
            return SUBST_FACTORY;
        }
        throw new IllegalStateException("Unreachable code");
}

   //绑定流程
   private final static void bind() {
        //-----------
        StaticLoggerBinder.getSingleton();
        //-----------
   }

}

org.slf4j.impl.StaticLoggerBinder

 
 private StaticLoggerBinder() {
        //使用了log4j
        loggerFactory = new Log4jLoggerFactory();
    }
三、总结

slf4j需要StaticLoggerBinder对象来完成绑定,所以其他的日志框架要想接入slf4j都要定义一个org.slf4j.impl.StaticLoggerBinder对象。 只不过返回的ILoggerFactory实现不一样。

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值