logback source read - configuration file parsing process (e)

Introduced in front of logback source initialization process is entrusted to ContextInitializer

StaticLoggerBinder

 void init() {
        try {
            try {
                (new ContextInitializer(this.defaultLoggerContext)).autoConfig();
            } catch (JoranException var2) {
                Util.report("Failed to auto configure default logger context", var2);
            }

            if (!StatusUtil.contextHasStatusListener(this.defaultLoggerContext)) {
                StatusPrinter.printInCaseOfErrorsOrWarnings(this.defaultLoggerContext);
            }

            this.contextSelectorBinder.init(this.defaultLoggerContext, KEY);
            this.initialized = true;
        } catch (Exception var3) {
            Util.report("Failed to instantiate [" + LoggerContext.class.getName() + "]", var3);
        }

    }

ContextInitializer

org.slf4j.impl.StaticLoggerBinder#init

->

ch.qos.logback.classic.util.ContextInitializer#autoConfig

public  void autoConfig () throws JoranException {
         / ** 
         * <. 1> Here configured to listen for messages configured 
         * system determines whether the parameter variables -Dlogback.statusListenerClass 
         * SYSOUT is equal to This is the default OnConsoleStatusListener console Printing 
         * otherwise configured as full path (creating a class that implements our own StatusListener) 
         * / 
        StatusListenerConfigHelper.installIfAsked ( the this .loggerContext);
         / ** 
         * here will successively look 
         * <2> from a lookup profile -Dlogback.configurationFile system variable = {file}. 
         * 2. If no then turn to find logback-test.xml logback.groovy logback.xml find any of the return 
         * / 
        the uRL of url = the this .findURLOfDefaultConfigurationFile (to true );
         IF (url =! null ) {
             // find the configuration file is the configuration file parsing configuration take 
           the this .configureByResource (url); 
        } the else {
             / ** 
             * This is mainly the SPI java extension points ServiceLoader If you want to implement your own this profile is defined by extension done 
             * / 
            Configurator C = (Configurator) EnvUtil.loadFromServiceLoader (Configurator. class );
             IF (! C = null ) {
                 the try { 
                    c.setContext ( the this .loggerContext); 
                    c.configure ( the this.loggerContext); 
                } the catch (Exception var4) {
                     the throw  new new LogbackException (String.format ( "the Failed to the initialize Configurator: the using the ServiceLoader% S", C =! null c.getClass () getCanonicalName (): "null"?. ) , var4); 
                } 
            } the else {
                 // do not use the extended SPI SPI default configuration may be extended via a reference 
                the BasicConfigurator BasicConfigurator = new new the BasicConfigurator (); 
                basicConfigurator.setContext ( the this .loggerContext); 
                BasicConfigurator.configure ( the this.loggerContext);
            }
        }

    }

At <1> main configuration file find the log listeners default console Print

 

 

 

 

 

 <2> at

configureByResource

org.slf4j.impl.StaticLoggerBinder#init

->

ch.qos.logback.classic.util.ContextInitializer#autoConfig#configureByResource

 public  void configureByResource (URL the URL) throws JoranException {
         IF (URL == null ) {
             the throw  new new an IllegalArgumentException ( "CAN Not BE null argument the URL" ); 
        } the else { 
            String the urlString = url.toString ();
             // if the profile is groovy according to the analysis of the end of groovy prevent general we are using xml so I do not see this step 
            IF (urlString.endsWith ( "groovy" )) {
                 IF (EnvUtil.isGroovyAvailable ()) { 
                    GafferUtil.runGafferConfiguratorOn ( the this .loggerContext, the this, url);
                } else {
                    StatusManager sm = this.loggerContext.getStatusManager();
                    sm.add(new ErrorStatus("Groovy classes are not available on the class path. ABORTING INITIALIZATION.", this.loggerContext));
                }
            } else {

                if (!urlString.endsWith("xml")) {
                    throw new LogbackException("Unexpected filename extension of file [" + url.toString() + "]. Should be either .groovy or .xml");
                }
                //If the end of the walking analytically xml xml was entrusted to JoranConfigurator 
                JoranConfigurator Configurator = new new JoranConfigurator (); 
                configurator.setContext ( the this .loggerContext); 
                configurator.doConfigure (URL); 
            } 

        } 
    }

JoranConfigurator

Class Diagram

doConfigure

ch.qos.logback.core.joran.GenericConfigurator#doConfigure(java.net.URL)

 

 public final void doConfigure(URL url) throws JoranException {
        InputStream in = null;
        boolean var12 = false;

        String errMsg;
        try {
            var12 = true;
            //暂时也不知道干啥的
            informContextOfURLUsedForConfiguration(this.getContext(), url);
            //获得一个连接对象 这里是FileURLConnection 可以想象是否可以支持http呢 就可以远程配置文件了
            URLConnection urlConnection = url.openConnection();
            //不使用缓存
            urlConnection.setUseCaches(false);
            //获取流
            in = urlConnection.getInputStream();
            //接下来看这个方法处理
            this.doConfigure(in, url.toExternalForm());
            var12 = false;
        } catch (IOException var15) {
            errMsg = "Could not open URL [" + url + "].";
            this.addError(errMsg, var15);
            throw new JoranException(errMsg, var15);
        } finally {
            if (var12) {
                if (in != null) {
                    try {
                        in.close();
                    } catch (IOException var13) {
                        String errMsg = "Could not close input stream";
                        this.addError(errMsg, var13);
                        throw new JoranException(errMsg, var13);
                    }
                }

            }
        }

        if (in != null) {
            try {
                in.close();
            } catch (IOException var14) {
                errMsg = "Could not close input stream";
                this.addError(errMsg, var14);
                throw new JoranException(errMsg, var14);
            }
        }

    }

ch.qos.logback.core.joran.GenericConfigurator#doConfigure#doConfigure

   public final void doConfigure(InputSource inputSource) throws JoranException {
        long threshold = System.currentTimeMillis();
        SaxEventRecorder recorder = new SaxEventRecorder(this.context);
        //<1>这里利用Sax解析xml 并封装成SaxEvent
        recorder.recordEvents(inputSource);
        //将封装成java对象的SaxEvent进行配置处理
        this.doConfigure(recorder.saxEventList);
        StatusUtil statusUtil = new StatusUtil(this.context);
        if (statusUtil.noXMLParsingErrorsOccurred(threshold)) {
            this.addInfo("Registering current configuration as safe fallback point");
            this.registerSafeConfiguration(recorder.saxEventList);
        }

    }

<1>

 

ch.qos.logback.core.joran.event.SaxEventRecorder#recordEvents

 

  public List<SaxEvent> recordEvents(InputSource inputSource) throws JoranException {
        SAXParser saxParser = this.buildSaxParser();

        try {
            //这里因为当前类继承了DefaultHandeler 所以通过这里将SAX解析成当前出席需要的对象
            saxParser.parse(inputSource, this);
            return this.saxEventList;
        } catch (IOException var4) {
            this.handleError("I/O error occurred while parsing xml file", var4);
        } catch (SAXException var5) {
            throw new JoranException("Problem parsing XML document. See previously reported errors.", var5);
        } catch (Exception var6) {
            this.handleError("Unexpected exception while parsing XML document.", var6);
        }
    }
    //解析开始标签
    public void startElement(String namespaceURI, String localName, String qName, Attributes atts) {
        String tagName = this.getTagName(localName, qName);
        this.globalElementPath.push(tagName);
        ElementPath current = this.globalElementPath.duplicate();
        this.saxEventList.add(new StartEvent(current, namespaceURI, localName, qName, atts, this.getLocator()));
    }
    //解析结束标签
    public void endElement(String namespaceURI, String localName, String qName) {
        this.saxEventList.add(new EndEvent(namespaceURI, localName, qName, this.getLocator()));
        this.globalElementPath.pop();
    }

 

Guess you like

Origin www.cnblogs.com/LQBlog/p/12166127.html