java log 初始化_slf4j + log4j 是如何初始化的

SLF4J的全称是 Simple Logging Facade for Java(简单java日志门面)

SLF4J自己不提供具体的日志功能实现,只是提供了一个统一的日志门面,在这个统一的门面之下,用户可以选择他们喜欢的日志的具体实现。

考虑下面一个场景:我们对外提供的工具包使用了log4j来管理日志,另外一个团队如果使用logback来管理他们的日志,在引入我们提供的工具包之后他们的项目中就会有两个不同的日志管理API,使用SLF4J可以解决这个问题。我们可以使用SLF4J + log4j来开发我们的工具包,客户端在使用我们的API的时候可以不用引入log4j的包

我们在使用SLF4J的时候通常使用下面的方式来得到Logger

Logger logger = LoggerFactory.getLogger(ClassName); //Logger 和LoggerFactory都是 slf4j-api.jar中 org.slf4j包下边的类

下边是getLogger的定义:

public staticLogger getLogger(String name) {

ILoggerFactory iLoggerFactory=getILoggerFactory();returniLoggerFactory.getLogger(name);

}

getILoggerFactory()方法最终调用的是 LoggerFactory的bind()方法来确定具体是加载哪个日志的实现

private final static voidbind() {try{

Set staticLoggerBinderPathSet = null;//skip check under android, see alsohttp://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);

replayEvents();

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

}

}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.");

}thrownsme;

}catch(Exception e) {

failedBinding(e);throw new IllegalStateException("Unexpected initialization failure", e);

}

}

findPossibleStaticLoggerBinderPathSet()方法会在calsspath中寻找名为org.slf4j.impl.StaticLoggerBinder的类来确定项目中有哪些具体的日志实现

针对log4j来说,我们如果要使用SLF4J + log4j 来管理我们的日志,则需要三个相关的jar包(slf4j-api.jar、slf4j-log4j12.jar、log4j.jar)。slf4j-api.jar中有Logger、LoggerFactory等相应的类,slf4j-log4j12.jar中有org.slf4j.impl.StaticLoggerBinder以及相应的 Log4jLoggerFactory 和能将log4j的Logger转换为slf4j的Logger的Log4jLoggerAdapter(下图是slf4j-log4j.jar中包含的类,一共6个:)

26057b851019c42d1e3565c2fcc3b027.png

org.slf4j.impl.StaticLoggerBinder类中绑定了Log4jLoggerFactory,在Log4jLoggerFactory的getLogger(String name)方法中使用 Log4jLoggerAdapter来实现了对log4j的注入:

publicLogger getLogger(String name) {

Logger slf4jLogger=loggerMap.get(name);if (slf4jLogger != null) {returnslf4jLogger;

}else{

org.apache.log4j.Logger log4jLogger;if(name.equalsIgnoreCase(Logger.ROOT_LOGGER_NAME))

log4jLogger=LogManager.getRootLogger();elselog4jLogger=LogManager.getLogger(name);

Logger newInstance= newLog4jLoggerAdapter(log4jLogger);

Logger oldInstance=loggerMap.putIfAbsent(name, newInstance);return oldInstance == null ?newInstance : oldInstance;

}

}

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值