Logback 中,用LogbackMDCAdapter实现了Sl4j里面的MDCAdapter接口。
下面是get 和 put 的代码实现:
publicclassLogbackMDCAdapterimplementsMDCAdapter{finalThreadLocal<Map<String,String>>copyOnThreadLocal=newThreadLocal<Map<String,String>>();privatestaticfinalintWRITE_OPERATION=1;privatestaticfinalintMAP_COPY_OPERATION=2;finalThreadLocal<Integer>lastOperation=newThreadLocal<Integer>();privateIntegergetAndSetLastOperation(intop){IntegerlastOp=lastOperation.get();lastOperation.set(op);returnlastOp;privatebooleanwasLastOpReadOrNull(IntegerlastOp){returnlastOp==null||lastOp.intValue()==MAP_COPY_OPERATION;privateMap<String,String>duplicateAndInsertNewMap(Map<String,String>oldMap){Map<String,String>newMap=Collections.synchronizedMap(newHashMap<String,String>());if(oldMap!=null){// we don't want the parent thread modifying oldMap while we are// iterating over itsynchronized(oldMap){newMap.putAll(oldMap);copyOnThreadLocal.set(newMap);returnnewMap;publicvoidput(Stringkey,Stringval)throwsIllegalArgumentException{if(key==null){thrownewIllegalArgumentException("key cannot be null");Map<String,String>oldMap=copyOnThreadLocal.get();IntegerlastOp=getAndSetLastOperation(WRITE_OPERATION);if(wasLastOpReadOrNull(lastOp)||oldMap==null){Map<String,String>newMap=duplicateAndInsertNewMap(oldMap);newMap.put(key,val);}else{oldMap.put(key,val);publicStringget(Stringkey){finalMap<String,String>map=copyOnThreadLocal.get();if((map!=null)&&(key!=null)){returnmap.get(key);}else{returnnull;// ...
packageorg.slf4j;publicfinalclassLoggerFactory{publicstaticLoggergetLogger(Stringname){ILoggerFactoryiLoggerFactory=getILoggerFactory();returniLoggerFactory.getLogger(name);publicstaticILoggerFactorygetILoggerFactory(){if(INITIALIZATION_STATE==UNINITIALIZED){synchronized(LoggerFactory.class){if(INITIALIZATION_STATE==UNINITIALIZED){INITIALIZATION_STATE=ONGOING_INITIALIZATION;performInitialization();switch(INITIALIZATION_STATE){caseSUCCESSFUL_INITIALIZATION:returnStaticLoggerBinder.getSingleton().getLoggerFactory();caseNOP_FALLBACK_INITIALIZATION:returnNOP_FALLBACK_FACTORY;caseFAILED_INITIALIZATION:thrownewIllegalStateException(UNSUCCESSFUL_INIT_MSG);caseONGOING_INITIALIZATION:returnSUBST_FACTORY;thrownewIllegalStateException("Unreachable code");privatefinalstaticvoidperformInitialization(){bind();if(INITIALIZATION_STATE==SUCCESSFUL_INITIALIZATION){versionSanityCheck();privatefinalstaticvoidbind(){try{Set<URL>staticLoggerBinderPathSet=null;if(!isAndroid()){staticLoggerBinderPathSet=findPossibleStaticLoggerBinderPathSet();reportMultipleBindingAmbiguity(staticLoggerBinderPathSet);// the next line does the bindingStaticLoggerBinder.getSingleton();INITIALIZATION_STATE=SUCCESSFUL_INITIALIZATION;reportActualBinding(staticLoggerBinderPathSet);fixSubstituteLoggers();replayEvents();SUBST_FACTORY.clear();}catch(NoClassDefFoundErrorncde){// ... }catch(java.lang.NoSuchMethodErrornsme){// ...}catch(Exceptione){// ...privatestaticStringSTATIC_LOGGER_BINDER_PATH="org/slf4j/impl/StaticLoggerBinder.class"
publicvoiddoConfigure(finalList<SaxEvent>eventList)throwsJoranException{buildInterpreter();// disallow simultaneous configurations of the same contextsynchronized(context.getConfigurationLock()){interpreter.getEventPlayer().play(eventList);
2.3 紧接着,执行EventPlayer的play方法,解析xml:
publicvoidplay(List<SaxEvent>aSaxEventList){eventList=aSaxEventList;SaxEventse;for(currentIndex=0;currentIndex<eventList.size();currentIndex++){se=eventList.get(currentIndex);if(seinstanceofStartEvent){interpreter.startElement((StartEvent)se);// invoke fireInPlay after startElement processinginterpreter.getInterpretationContext().fireInPlay(se);if(seinstanceofBodyEvent){// invoke fireInPlay before characters processinginterpreter.getInterpretationContext().fireInPlay(se);interpreter.characters((BodyEvent)se);if(seinstanceofEndEvent){// invoke fireInPlay before endElement processinginterpreter.getInterpretationContext().fireInPlay(se);interpreter.endElement((EndEvent)se);
publicParser(Stringpattern,IEscapeUtilescapeUtil)throwsScanException{try{TokenStreamts=newTokenStream(pattern,escapeUtil);this.tokenList=ts.tokenize();}catch(IllegalArgumentExceptionnpe){thrownewScanException("Failed to initialize Parser",npe);
classCompiler<E>extendsContextAwareBase{Converter<E>compile(){head=tail=null;for(Noden=top;n!=null;n=n.next){switch(n.type){caseNode.LITERAL:addToList(newLiteralConverter<E>((String)n.getValue()));break;caseNode.COMPOSITE_KEYWORD:CompositeNodecn=(CompositeNode)n;CompositeConverter<E>compositeConverter=createCompositeConverter(cn);if(compositeConverter==null){addError("Failed to create converter for [%"+cn.getValue()+"] keyword");addToList(newLiteralConverter<E>("%PARSER_ERROR["+cn.getValue()+"]"));break;compositeConverter.setFormattingInfo(cn.getFormatInfo());compositeConverter.setOptionList(cn.getOptions());Compiler<E>childCompiler=newCompiler<E>(cn.getChildNode(),converterMap);childCompiler.setContext(context);Converter<E>childConverter=childCompiler.compile();compositeConverter.setChildConverter(childConverter);addToList(compositeConverter);break;caseNode.SIMPLE_KEYWORD:SimpleKeywordNodekn=(SimpleKeywordNode)n;DynamicConverter<E>dynaConverter=createConverter(kn);if(dynaConverter!=null){dynaConverter.setFormattingInfo(kn.getFormatInfo());dynaConverter.setOptionList(kn.getOptions());addToList(dynaConverter);}else{// if the appropriate dynaconverter cannot be found, then replace// it with a dummy LiteralConverter indicating an error.Converter<E>errConveter=newLiteralConverter<E>("%PARSER_ERROR["+kn.getValue()+"]");addStatus(newErrorStatus("["+kn.getValue()+"] is not a valid conversion word",this));addToList(errConveter);returnhead;
publicfinalclassLoggerimplementsorg.slf4j.Logger,LocationAwareLogger,AppenderAttachable<ILoggingEvent>,Serializable{privatevoidfilterAndLog_0_Or3Plus(finalStringlocalFQCN,finalMarkermarker,finalLevellevel,finalStringmsg,finalObject[]params,finalThrowablet){finalFilterReplydecision=loggerContext.getTurboFilterChainDecision_0_3OrMore(marker,this,level,msg,params,t);if(decision==FilterReply.NEUTRAL){if(effectiveLevelInt>level.levelInt){return;}elseif(decision==FilterReply.DENY){return;buildLoggingEventAndAppend(localFQCN,marker,level,msg,params,t);privatevoidbuildLoggingEventAndAppend(finalStringlocalFQCN,finalMarkermarker,finalLevellevel,finalStringmsg,finalObject[]params,finalThrowablet){LoggingEventle=newLoggingEvent(localFQCN,this,level,msg,t,params);le.setMarker(marker);callAppenders(le);publicvoidcallAppenders(ILoggingEventevent){intwrites=0;for(Loggerl=this;l!=null;l=l.parent){writes+=l.appendLoopOnAppenders(event);if(!l.additive){break;// No appenders in hierarchyif(writes==0){loggerContext.noAppenderDefinedWarning(this);privateintappendLoopOnAppenders(ILoggingEventevent){if(aai!=null){returnaai.appendLoopOnAppenders(event);}else{return0;
publicclassOutputStreamAppender<E>extendsUnsynchronizedAppenderBase<E>{@Overrideprotectedvoidappend(EeventObject){if(!isStarted()){return;subAppend(eventObject);protectedvoidsubAppend(Eevent){if(!isStarted()){return;try{if(eventinstanceofDeferredProcessingAware){((DeferredProcessingAware)event).prepareForDeferredProcessing();lock.lock();try{writeOut(event);}finally{lock.unlock();}catch(IOExceptionioe){this.started=false;addStatus(newErrorStatus("IO failure in appender",this,ioe));protectedvoidwriteOut(Eevent)throwsIOException{this.encoder.doEncode(event);
publicMap<String,String>getMDCPropertyMap(){// populate mdcPropertyMap if nullif(mdcPropertyMap==null){MDCAdaptermdc=MDC.getMDCAdapter();if(mdcinstanceofLogbackMDCAdapter)mdcPropertyMap=((LogbackMDCAdapter)mdc).getPropertyMap();mdcPropertyMap=mdc.getCopyOfContextMap();// mdcPropertyMap still null, use emptyMap()if(mdcPropertyMap==null)