Spring Boot Learning Notes 03--deep understanding of the Springboot startup process

Source: Internet
Author: User
Tags event listener throwable java se

Summary

After reading this article you will grasp the following knowledge points: The role of springapplication and the operation process of Springbootservletinitializer and operation process

PS: This section is slightly boring, if you are not interested in the Springboot startup process, you can skip.

springboot Series : Spring boot Learning Notes deep understanding of Springapplication

@SpringBootApplication public
class Springbootwebdemoapplication {public
    static void Main (string[] args) {
        Springapplication.run (Springbootwebdemoapplication.class, args);
    }

This is the Springboot launch entrance, through the previous study we have a general understanding of the role of @SpringBootApplication , then we come to know springapplication.
Springapplication (Spring Boot Docs 1.4.2.RELEASE API). Springapplication.run (Springbootwebdemoapplication.class, args);

Through the source, let's take a look at the execution of the Springapplication.run () method
1. Invoke the static method

1 public
static Configurableapplicationcontext run (Object source, String ... args) {return run (new Object[]{source }, args);
public static Configurableapplicationcontext run (object[] sources, string[] args) 
{return (new Springapplication ( Sources)). Run (args);

2. Create a Springapplication object

2 public
springapplication (Object ... sources) {
        this.bannermode = mode.console;//banner Print mode, this is console mode
        This.logstartupinfo = true;//open log
        this.addcommandlineproperties = true;//Enable Commandlineproperties
        this.headless = true;//Open headless mode support
        This.registershutdownhook = true;//Enable registration Shutdownhook to shut down IOC containers and resources in non-web applications
        this.additionalprofiles = new HashSet ();
        This.initialize (sources);//Initialize
    }

Ps:headless reference: Using headless mode on the Java SE platform

3. Initialize related objects and properties

3
private void Initialize (object[] sources) {
        if (sources!= null && sources.length > 0) {
            THIS.S Ources.addall (arrays.aslist (sources));
        }
        3.1 To determine if the WEB is running environment, returns true if the Classpath contains all classes specified by **web_environment_classes**
        this.webenvironment = This.deducewebenvironment ();
        3.2 The implementation class of all Applicationcontextinitializer declared in *meta-inf/spring.factories* is found and instantiated
        this.setinitializers ( This.getspringfactoriesinstances (Applicationcontextinitializer.class));
        3.3 The implementation class of all Applicationlistener declared in *meta-inf/spring.factories* is found and instantiated
        this.setlisteners ( This.getspringfactoriesinstances (Applicationlistener.class));
        3.4 Gets the class object that currently executes the main method, here is the instance of springbootwebdemoapplication
        This.mainapplicationclass = This.deducemainapplicationclass ();
    }

3.1 Determine if it is a web-run environment
Returns True if the Classpath contains all the classes specified by web_environment_classes , and is used to create ApplicationContext objects of the specified type.

3.1
private static final string[] web_environment_classes = new string[]{"Javax.servlet.Servlet", " Org.springframework.web.context.ConfigurableWebApplicationContext "};

3.2 The general process is to retrieve the meta-inf/spring.factories by Springfactoriesloader, find the implementation class of all Applicationcontextinitializer declared and instantiate it.
Applicationcontextinitializer is an interface in the spring framework that can be understood to be useful before ApplicationContext performs the refresh Call the Applicationcontextinitializer Initialize () method to further set up and process the applicationcontext.

Public interface Applicationcontextinitializer<c extends configurableapplicationcontext> {
    void Initialize (C var1);
}

The meta-inf/spring.factories contained in the Spring-boot-1.4.2.release.jar is applicationcontextinitializer

# application Context initializers
org.springframework.context.applicationcontextinitializer=\
Org.springframework.boot.context.configurationwarningsapplicationcontextinitializer,\
Org.springframework.boot.context.contextidapplicationcontextinitializer,\
Org.springframework.boot.context.config.delegatingapplicationcontextinitializer,\
Org.springframework.boot.context.web.ServerPortInfoApplicationContextInitializer

The meta-inf/spring.factories contained in the Spring-boot-autoconfigure-1.4.2.release.jar is Applicationcontextinitializer

# initializers
org.springframework.context.applicationcontextinitializer=\
Org.springframework.boot.autoconfigure.sharedmetadatareaderfactorycontextinitializer,\
Org.springframework.boot.autoconfigure.logging.AutoConfigurationReportLoggingInitializer

3.3 The general process is to retrieve the meta-inf/spring.factories by Springfactoriesloader, find the implementation class of all Applicationlistener declared and instantiate it.
Applicationlistener is an interface in the spring framework, the event listener, which can be understood to be used by the springapplicationrunlistener when a notification event is issued Applicationlistener is responsible for receiving.

Public interface Applicationlistener<e extends applicationevent> extends EventListener {
    void Onapplicationevent (E var1);
}

Springboot only provides a Springapplicationrunlistener implementation class, which is Eventpublishingrunlistener, It works by registering the Applicationlistener listener during the Springboot startup, releasing different event types at different points in the process, and if there are Applicationlistener implementation classes that listen to these events, You can receive and process it.

Public interface Springapplicationrunlistener {
    //Notification listener, Springboot begins execution of
    Void started ();
    Notifies the listener that environment is ready to complete the
    void environmentprepared (Configurableenvironment var1);
    Notifies the listener that ApplicationContext has created and initialized the
    void contextprepared (Configurableapplicationcontext var1);
    Notifies the listener that ApplicationContext has completed the IOC configuration loaded
    void contextloaded (Configurableapplicationcontext var1);
    Notifies the listener that the Springboot boot completes the
    void finished (Configurableapplicationcontext var1, Throwable var2);

The meta-inf/spring.factories contained in the Spring-boot-1.4.2.release.jar is applicationlistener

# application Listeners
org.springframework.context.applicationlistener=\
Org.springframework.boot.clearcachesapplicationlistener,\
Org.springframework.boot.builder.parentcontextcloserapplicationlistener,\
Org.springframework.boot.context.fileencodingapplicationlistener,\
Org.springframework.boot.context.config.ansioutputapplicationlistener,\
Org.springframework.boot.context.config.configfileapplicationlistener,\
Org.springframework.boot.context.config.delegatingapplicationlistener,\
Org.springframework.boot.liquibase.liquibaseservicelocatorapplicationlistener,\
Org.springframework.boot.logging.classpathloggingapplicationlistener,\
Org.springframework.boot.logging.LoggingApplicationListener

The meta-inf/spring.factories contained in the Spring-boot-autoconfigure-1.4.2.release.jar is applicationlistener

# application Listeners
org.springframework.context.applicationlistener=\
Org.springframework.boot.autoconfigure.BackgroundPreinitializer

The meta-inf/spring.factories contained in the Spring-boot-1.4.2.release.jar is springapplicationrunlistener

# Run Listeners
org.springframework.boot.springapplicationrunlistener=\
Org.springframework.boot.context.event.EventPublishingRunListener

3.4 Gets the class object that currently executes the main method, which is the instance of Springbootwebdemoapplication.

4. Core approach

4 Public Configurableapplicationcontext run (String ... args) {//Open task Execution time listener Stopwatch stopwatch = new St
        Opwatch ();

        Stopwatch.start ();
        Configurableapplicationcontext context = null;

        Object analyzers = null;

        Set the system property "Java.awt.headless" to true to enable the Headless mode support This.configureheadlessproperty ();
        Retrieves the *meta-inf/spring.factories* by *springfactoriesloader*,//finds the implementation class of all declared Springapplicationrunlistener and instantiates it.
        Then call its started () method one by one, and the broadcast springboot to begin execution.
        Springapplicationrunlisteners listeners = this.getrunlisteners (args);

        Listeners.started ();

            try {defaultapplicationarguments ex = new defaultapplicationarguments (args); Create and configure the environment that the current Springboot application will use (including the configuration to use Propertysource and profile),//and traverse the call to all Springapplicationrunlistener
            Environmentprepared () method, broadcast environment ready to complete.

  Configurableenvironment environment = this.prepareenvironment (listeners, ex);          Decide whether to print Banner Banner printedbanner = this.printbanner (Environment); Depending on the value of the webenvironment, determine what type of ApplicationContext object to create or, if it is a Web environment, create Org.springframework.boot.context.embedded.Ann Otationconfigembeddedwebapplicationcontext//otherwise create org.springframework.context.annotation.AnnotationConfigApplic

            Ationcontext context = This.createapplicationcontext ();

            Register the exception Parser new failureanalyzers (context);
            Load environment for ApplicationContext, and then execute the Applicationcontextinitializer Initialize () method to further encapsulate ApplicationContext. and call all the Springapplicationrunlistener contextprepared () methods, "Eventpublishingrunlistener only provides an empty contextprepared ()
            method,//After initializing the IOC container, and invoking the Springapplicationrunlistener contextloaded () method, the broadcast ApplicationContext IOC loading completes,
            This includes a variety of automatic configuration classes that are imported through the * * @EnableAutoConfiguration * *.

            This.preparecontext (context, environment, listeners, ex, Printedbanner); InitialTo all automatic configuration classes, call the ApplicationContext Refresh () method This.refreshcontext (context);
            Traverse all registered Applicationrunner and Commandlinerunner, and execute its run () method. This process can be understood to be the last step before Springboot completes ApplicationContext initialization,//We can implement our own Applicationrunner or Commandlinerunner to spring
            The boot process is extended.

            This.afterrefresh (context, ex);
            Calling all Springapplicationrunlistener finished () methods, the broadcast Springboot has completed the process of ApplicationContext initialization.

            Listeners.finished (context, (throwable) null);
            Close task Execution Time Listener stopwatch.stop (); If the log is turned on, then the execution is time if (This.logstartupinfo) {(New Startupinfologger (This.mainapplicationclass))
            . logstarted (This.getapplicationlog (), stopwatch);
        return to context; catch (Throwable var9) {//Call Exception Analyzer Print report, call all Springapplicationrunlistener finished () method to publish exception information out T His.handlerunfailure (context, listeners, (failureanalyzers) analyzers, var9);
        throw new IllegalStateException (VAR9); }
    }

The meta-inf/spring.factories contained in the Spring-boot-1.4.2.release.jar contains failureanalyzer and Failureanalysisreporters

# failure Analyzers
org.springframework.boot.diagnostics.failureanalyzer=\
Org.springframework.boot.diagnostics.analyzer.beancurrentlyincreationfailureanalyzer,\
Org.springframework.boot.diagnostics.analyzer.beannotofrequiredtypefailureanalyzer,\
Org.springframework.boot.diagnostics.analyzer.bindfailureanalyzer,\
Org.springframework.boot.diagnostics.analyzer.connectorstartfailureanalyzer,\
Org.springframework.boot.diagnostics.analyzer.nouniquebeandefinitionfailureanalyzer,\
Org.springframework.boot.diagnostics.analyzer.portinusefailureanalyzer,\
Org.springframework.boot.diagnostics.analyzer.ValidationExceptionFailureAnalyzer

# Failureanalysisreporters
org.springframework.boot.diagnostics.failureanalysisreporter=\
Org.springframework.boot.diagnostics.LoggingFailureAnalysisReporter

Description The Springboot start process is actually the initialization process for the ApplicationContext. ApplicationContext is set up immediately after the creation of the environmen and is further encapsulated by Applicationcontextinitializer . Various broadcast events are released at various points in the ApplicationContext initialization process by Springapplicationrunlistener, and the Applicationlistener is responsible for receiving broadcast events. The IOC is injected during initialization, including various automatic configuration classes that are imported through the @EnableAutoConfiguration . The implementation class that invokes Applicationrunner and Commandlinerunner before initialization completes. Extended Springapplication

Through the above study, we basically understand that if we want to expand the springapplication, we can choose the following three scenarios: Create Applicationcontextinitializer Implementation class Create a Applicationlistener implementation class to create an implementation class for Applicationrunner and Commandlinerunner

1. The custom Applicationcontextinitializer and Applicationlistener can be loaded in the following way

@SpringBootApplication public
class Springbootwebdemoapplication {public
    static void Main (string[] args) {
        //springapplication.run (Springbootwebdemoapplication.class, args);
        Springapplication springapplication = new Springapplication (springbootwebdemoapplication.class);

        Springapplication.addinitializers (myapplicationcontextinitializer1,myapplicationcontextinitializer2);

        Springapplication.addlisteners (myapplicationlistener1,myapplicationlistener2);

        Springapplication.run (args);
    }

2. You can also create meta-inf/spring.factories files under the classpath of the current project and declare the corresponding Applicationcontextinitializer and Applicationlistener

Org.springframework.context.applicationcontextinitializer=\
xxx.xxx.myapplicationcontextinitializer1,\
xxx.xxx.MyApplicationContextInitializer2

# application Listeners
Org.springframework.context.applicationlistener=\
xxx.xxx.myapplicationlistener1,\
Xxx.xxx.MyApplicationListener2

3. As for Applicationrunner and Commandlinerunner, simply add @Component annotations to their implementation classes or inject them through @bean annotations in the @configuration configuration class. deep understanding of Springbootservletinitializer

After familiar with the principle of springapplication , it is easier for us to understand the principle of Springbootservletinitializer .

public class Servletinitializer extends Springbootservletinitializer {

    @Override
    protected Springapplicationbuilder Configure (Springapplicationbuilder application) {return
        application.sources ( Demowarapplication.class);
    }

Springbootservletinitializer is a org.springframework.web.context.WebApplicationContext, and the container starts by calling its Onstartup ( ServletContext ServletContext) method, Next I will take a look at this method:

public void Onstartup (ServletContext servletcontext) throws Servletexception {
        This.logger = Logfactory.getlog ( This.getclass ());
        Final Webapplicationcontext Rootappcontext = This.createrootapplicationcontext (ServletContext);
        if (Rootappcontext!= null) {
            Servletcontext.addlistener (new Contextloaderlistener (rootappcontext) {
                public void Contextinitialized (Servletcontextevent event) {
                }}
            );
        else {
            this.logger.debug ("No Contextloaderlistener registered, as Createrootapplicationcontext () did Application Context ");
        }

    }

The core approach here is Createrootapplicationcontext (ServletContext):

Protected Webapplicationcontext Createrootapplicationcontext (ServletContext servletcontext) {//Create Springapplicati
        Onbuilder, and using it to produce springapplication object Springapplicationbuilder builder = This.createspringapplicationbuilder ();

        Builder.main (This.getclass ());
        ApplicationContext parent = This.getexistingrootwebapplicationcontext (ServletContext);
            if (parent!= null) {This.logger.info ("Root context already created (using as parent.");
            Servletcontext.setattribute (Webapplicationcontext.root_web_application_context_attribute, (Object) null); Builder.initializers (New Applicationcontextinitializer[]{new Parentcontextapplicationcontextinitializer (parent)}
        );
        }//Initialize and encapsulate Springapplicationbuilder objects, prepare for Springapplication objects to add Applicationcontextinitializer and Applicationlistener Builder.initializers (New Applicationcontextinitializer[]{new Servletcontextapplicationcontextinitializer (
        ServletContext)}); BuIlder.listeners (New Applicationlistener[]{new Servletcontextapplicationlistener (ServletContext)});

        Specifies the ApplicationContext type Builder.contextclass (Annotationconfigembeddedwebapplicationcontext.class) that is created; Passing the entry class and constructing the Springapplication object//can extend the Springbootservletinitializer through the Configure () Method builder = This.configu
        Re (builder);

        Springapplication application = Builder.build (); if (Application.getsources (). IsEmpty () && annotationutils.findannotation (This.getclass (),
        Configuration.class)!= null) {application.getsources (). Add (This.getclass ()); } assert.state (!application.getsources (). IsEmpty (), "No springapplication sources have. been defined.
        Either override the Configure method or add an @Configuration annotation ");
        if (this.registererrorpagefilter) {application.getsources (). Add (Errorpagefilter.class); ///finally invoke the Springapplication Run method return This.run (ApplicatiON); }

Description
The Springbootservletinitializer
execution process, in simple terms, is to build and encapsulate springapplication objects through Springapplicationbuilder, And eventually call the Springapplication run method. Extended Springbootservletinitializer

Similar to the extended springapplication, Applicationcontextinitializer and Applicationlistener can be extended based on the public method provided by Springapplicationbuilder

public class Servletinitializer extends Springbootservletinitializer {

    @Override
    protected Springapplicationbuilder Configure (Springapplicationbuilder application) {
        application.initializers ( MYAPPLICATIONCONTEXTINITIALIZER1,MYAPPLICATIONCONTEXTINITIALIZER2);
        Application.listeners (myapplicationlistener1,myapplicationlistener2) return
        application.sources ( Demowarapplication.class);
    }


http://www.jianshu.com/p/cb5cb5937686


Contact Us

The content source of this page is from Internet, which doesn't represent Alibaba Cloud's opinion; products and services mentioned on that page don't have any relationship with Alibaba Cloud. If the content of the page makes you feel confusing, please write us an email, we will handle the problem within 5 days after receiving your email.

If you find any instances of plagiarism from the community, please send an email to: info-contact@alibabacloud.com and provide relevant evidence. A staff member will contact you within 5 working days.

A Free Trial That Lets You Build Big!

Start building with 50+ products and up to 12 months usage for Elastic Compute Service

  • Sales Support

    1 on 1 presale consultation

  • After-Sales Support

    24/7 Technical Support 6 Free Tickets per Quarter Faster Response

  • Alibaba Cloud offers highly flexible support services tailored to meet your exact needs.