Location>code7788 >text

Fourth, the analysis of the underlying mechanism of Spring Boot (Tomcat startup analysis + Spring container initialization + Tomcat how to associate Spring container) and the individual to write a startup Tomcat

Popularity:606 ℃/2024-08-30 20:56:46

Fourth, the analysis of the underlying mechanism of Spring Boot (Tomcat startup analysis + Spring container initialization + Tomcat how to associate Spring container) and the individual to write a startup Tomcat

@

catalogs
  • Fourth, the analysis of the underlying mechanism of Spring Boot (Tomcat startup analysis + Spring container initialization + Tomcat how to associate Spring container) and the individual to write a startup Tomcat
  • 1. source code analysis Spring Boot is how to start Tomcat, and support access to @Controller Debug process analysis
    • 1.1 Source code analysis: ( ) method
  • 2. write their own implementation of Spring Boot underlying mechanism [Tomcat startup analysis + Spring container initialization + Tomcat how to associate Spring container].
    • 2.1 Realize Task 1: Create Tomcat and start it.
    • 2.2 Realize task phase 2: create Spring container
    • 2.3 Implement Task Phase 3: Associate Tomcat with the Spring container and start the Spring container
  • 3. Finally:


1. Source code analysis Spring Boot is how to start Tomcat, and support access to @Controller Debug process analysis

To analyze the source code, naturally, Debug is indispensable. Let's hit thebreakpoint Debug up.

1.1 Source code analysis: ( ) method

()
DeBug (, args); see how Spring Boot starts Tomcat

Our Debug goal: to hold on to a thread of code that sees tomcat being started: e.g.()

在这里插入图片描述

在这里插入图片描述

// Here we go. Debug SpringApplication。run()
   public static ConfigurableApplicationContext run(Class<?> primarySource, String... args) {
        return run(new Class[]{primarySource}, args);
    }

在这里插入图片描述


    public static ConfigurableApplicationContext run(Class<?>[] primarySources, String[] args) {
        return (new SpringApplication(primarySources)).run(args);
    }

在这里插入图片描述

在这里插入图片描述

 public ConfigurableApplicationContext run(String... args) {
        StopWatch stopWatch = new StopWatch();
        ();
        DefaultBootstrapContext bootstrapContext = ();
        ConfigurableApplicationContext context = null;
        ();
        SpringApplicationRunListeners listeners = (args);
        (bootstrapContext, );

        try {
            ApplicationArguments applicationArguments = new DefaultApplicationArguments(args);
            ConfigurableEnvironment environment = (listeners, bootstrapContext, applicationArguments);
            (environment);
            Banner printedBanner = (environment);
            context = (); // Special analysis: Creating Containers
            ();
            (bootstrapContext, context, environment, listeners, applicationArguments, printedBanner);
            (context); // Special analysis:Refreshing the application context,for example:Initialize Default Settings/Injecting relevantBean/activate (a plan) tomcat
            (context, applicationArguments);
            ();
            if () {
                (new StartupInfoLogger()).logStarted((), stopWatch);
            }

            (context);
            (context, applicationArguments);
        } catch (Throwable var10) {
            (context, var10, listeners);
            throw new IllegalStateException(var10);
        }

        try {
            (context);
            return context;
        } catch (Throwable var9) {
            (context, var9, (SpringApplicationRunListeners)null);
            throw new IllegalStateException(var9);
        }
    }
  1. : There are many types of containers, and the corresponding container will be created based on your
    The default is a servlet, which is the web container/processing servlet.

在这里插入图片描述


    protected ConfigurableApplicationContext createApplicationContext() {
        return ();
    }


  1. The default is to go to this branch case SERVLET: return new AnnotationConfigServletWebServerApplicationContext();

在这里插入图片描述

public interface ApplicationContextFactory {
    ApplicationContextFactory DEFAULT = (webApplicationType) -> {
        try {
            switch(webApplicationType) {
            case SERVLET:  // The default is to go into this branch
                return new AnnotationConfigServletWebServerApplicationContext();
            case REACTIVE:
                return new AnnotationConfigReactiveWebServerApplicationContext();
            default:
                return new AnnotationConfigApplicationContext();
            }
        } catch (Exception var2) {
            throw new IllegalStateException("Unable create a default ApplicationContext instance, you may need a custom ApplicationContextFactory", var2);
        }
    };

    ConfigurableApplicationContext create(WebApplicationType webApplicationType);

    static ApplicationContextFactory ofContextClass(Class<? extends ConfigurableApplicationContext> contextClass) {
        return of(() -> {
            return (ConfigurableApplicationContext)(contextClass);
        });
    }

    static ApplicationContextFactory of(Supplier<ConfigurableApplicationContext> supplier) {
        return (webApplicationType) -> {
            return (ConfigurableApplicationContext)();
        };
    }
}

在这里插入图片描述

在这里插入图片描述

    private void refreshContext(ConfigurableApplicationContext context) {
        if () {
            (context);
        }
        (context); // Special analysis,Real implementation of relevant mandates
    }

在这里插入图片描述


    protected void refresh(ConfigurableApplicationContext applicationContext) {
        ();
    }
  1. Servlet in the

在这里插入图片描述

    public final void refresh() throws BeansException, IllegalStateException {
        try {
            (); // Analyze this method in particular
        } catch (RuntimeException var3) {
            WebServer webServer = ;
            if (webServer != null) {
                ();
            }

            throw var3;
        }
    }
  1. ApplicationContextFactory .java

在这里插入图片描述


 public void refresh() throws BeansException, IllegalStateException {
        synchronized() {
            StartupStep contextRefresh = ("");
            ();
            ConfigurableListableBeanFactory beanFactory = ();
            (beanFactory);

            try {
                (beanFactory);
                StartupStep beanPostProcess = ("-process");
                (beanFactory);
                (beanFactory);
                ();
                ();
                ();
                (); // Special analysis,When the parent class has finished generalizing,Re-dynamically bind the mechanism back to the
                ();
                (beanFactory);
                ();
            } catch (BeansException var10) {
                if (()) {
                    ("Exception encountered during context initialization - cancelling refresh attempt: " + var10);
                }

                ();
                (var10);
                throw var10;
            } finally {
                ();
                ();
            }

        }
    }

  1. 在这里插入图片描述

 protected void onRefresh() {
        ();

        try {
            (); establish webServer 可以理解成会establish指定 webserver (computer)-tomcat
        } catch (Throwable var2) {
            throw new ApplicationContextException("Unable to start web server", var2);
        }
    }

在这里插入图片描述
在这里插入图片描述

在这里插入图片描述

在这里插入图片描述

 private void createWebServer() {
        WebServer webServer = ;
        ServletContext servletContext = ();
        if (webServer == null && servletContext == null) {
            StartupStep createWebServer = ().start("");
            ServletWebServerFactory factory = ();
            ("factory", ().toString());
             = (new ServletContextInitializer[]{
()}); // Special analysis,utilization TomcatServletWebServerFactory Create aTomcatWEbServer
            ();
            ().registerSingleton("webServerGracefulShutdown", new WebServerGracefulShutdownLifecycle());
            ().registerSingleton("webServerStartStop", new WebServerStartStopLifecycle(this, ));
        } else if (servletContext != null) {
            try {
                ().onStartup(servletContext);
            } catch (ServletException var5) {
                throw new ApplicationContextException("Cannot initialize servlet context", var5);
            }
        }

        ();
    }

Tomcat will be created and started.

在这里插入图片描述

 public WebServer getWebServer(ServletContextInitializer... initializers) {
        if () {
            ();
        }

        Tomcat tomcat = new Tomcat();
        File baseDir =  != null ?  : ("tomcat");
        (());
        Connector connector = new Connector();
        (true);
        ().addConnector(connector);
        (connector);
        (connector);
        ().setAutoDeploy(false);
        (());
        Iterator var5 = ();

        while(()) {
            Connector additionalConnector = (Connector)();
            ().addConnector(additionalConnector);
        }

        ((), initializers);
        return (tomcat);
    }

在这里插入图片描述


    protected TomcatWebServer getTomcatWebServer(Tomcat tomcat) {
        return new TomcatWebServer(tomcat, () >= 0, ());
    }

在这里插入图片描述

    public TomcatWebServer(Tomcat tomcat, boolean autoStart, Shutdown shutdown) {
         = new Object();
         = new HashMap();
        (tomcat, "Tomcat Server must not be null");
         = tomcat;
         = autoStart;
         = shutdown == ? new GracefulShutdown(tomcat) : null;
        (); // Analyze this method
    }
  1. (); Initializes the Tomcat server.

在这里插入图片描述

 private void initialize() throws WebServerException {
        ("Tomcat initialized with port(s): " + (false));
        synchronized() {
            try {
                ();
                Context context = ();
                ((event) -> {
                    if ((()) && "start".equals(())) {
                        ();
                    }

                });
                (); // ********* activate (a plan) Tomcat
                ();

                try {
                    (context, (), ().getClassLoader());
                } catch (NamingException var5) {
                }

                ();
            } catch (Exception var6) {
                ();
                ();
                throw new WebServerException("Unable to start embedded Tomcat", var6);
            }

        }
    }

2. write their own implementation of Spring Boot underlying mechanism [Tomcat startup analysis + Spring container initialization + Tomcat how to associate Spring container].

**Spring Boot injection to hit the ioc container: the underlying mechanism: is still: we implement the Spring container that set of mechanismsIO/File Scanning + Annotation + Reflection + Collections + Mapping ** 。

Rely on Maven to configure the appropriate requiredjar Package.

在这里插入图片描述

<?xml version="1.0" encoding="UTF-8"? >;xml version="1.0" encoding="UTF-8"?
<project xmlns="/POM/4.0.0"
         xmlns:xsi="http:///2001/XMLSchema-instance"
         xsi:schemaLocation="/POM/4.0.0 /xsd/maven-4.0." >
    <modelVersion>4.0.0</modelVersion>

    <groupId></groupId>
    <artifactId>mySpringBoot</artifactId>
    <version>1.0-SNAPSHOT</version>

    <! -- Importing SpringBoot parent project - prescribed writeups - >
    <parent>
        <groupId> </groupId>
        <artifactId>spring-boot-starter-parent</artifactId>
        <version>2.5.3</version>
    </parent>


    <! -- Import web project scenario launcher: will automatically import all dependencies [libraries/jars] of jar packages related to web development -- <!
    <! -- Later on, we will explain what dependencies spring-boot-starter-web introduces -- > <!
    <dependencies>
        <dependency>
            <groupId> </groupId>
            <artifactId>spring-boot-starter-web</artifactId>
<! --
        Since we have to create the Tomcat object and start it ourselves.
        So let's exclude the embedded spring-boot-starter-tomcat first.
-->
            <exclusions>;
                <exclusions>
                    <groupId> </groupId>.
                    <artifactId>spring-boot-starter-web</artifactId>.
                </exclusion>
            </exclusions>
        </dependency>.

<! -- We specify the tomcat version and introduce tomcat dependencies/libraries -- >!
<! --
            1. Use the specified tomcat 8.5.75, and ask your friends to bring in this version as well.
            2. If we introduce our own specified tomcat, we must remember to exclude spring-boot-stater-tomcat from the front.
            3. If you do not exclude, there will be GenericServlet Not Found error.
-->
        <dependency>.
            <groupId> </groupId>
            <artifactId>tomcat-embed-core</artifactId>
            <version>8.5.75</version>
        </dependency>

        </dependency> <dependency>
            <groupId> </groupId> </groupId>
            <artifactId>tomcat-jasper</artifactId> <groupId></groupId>
            <version>8.5.75</version>
        </dependency>
    </dependencies>

</project>.

2.1 Realize Task 1: Create Tomcat and start it.

在这里插入图片描述

package ;


import ;

public class MySpringApplication {

    // Here we create a tomcat object and associate it with the Spring container and start it up
    public static void run() {

        try {
            // Create the tomcat object
            Tomcat tomcat = new Tomcat(); // Create a tomcat object.

            // 1. Make it possible for tomcat to forward requests to the spring web container.
            // 2. "/myspboot" is the application context of our project, which is what we specified when we configured tomcat.
            ("/app", "E:\\\Java\\\SpringBoot\\quickstart\\mySpringBoot");

            //
            // Set the monitor port to 9090
            (8080).

            // Start Tomcat
            (); // Start Tomcat.

            // Wait for the request to come in
            ("===9090=== Waiting for request ========="); ("===9090=== Waiting for request ========="); ().await(); // Wait for request access.
            ().await();

        } catch (Exception e) {
            (); } catch (Exception e) {
        } finally {

        }
    }
}

2.2 Realize task phase 2: create Spring container

bean object.

在这里插入图片描述

package ;


import ;

@Controller // Add to ioc container to manage
public class Monster {

}

The config configuration class for the bean object

在这里插入图片描述

package ;


import ;
import ;
import ;
import ;


/*
Here is a question, how does the container know which packages to scan?
The packages to be scanned can be specified in the configuration class: @ComponentScan("")
MyConfig Configuration Class - as a configuration file for Spring
 */
@ComponentScan("")
@Configuration // Labeling: setup class
public class MyConfig {

    // Inject the bean - monster object into the Spring container.
    @Bean
    public Monster monster() {
        return new Monster();
    }

}

controller The controller that handles the business request

在这里插入图片描述

package ;


import ;
import ;

@RestController // @Controller + @ResponseBod
public class MyHiController {

    @RequestMapping("/myhi") // Setting the request mapping path
    public String hi() {
        return "hi my MyHiController ";
    }

}

2.3 Implement Task Phase 3: Associate Tomcat with the Spring container and start the Spring container

在这里插入图片描述

package ;

import ;
import ;
import ;
import ;
import ;import ;import ;import ;import
import ;

import ;import ;import ;import ;import
import ;import ;import ;import ;import
import ;


/**
 * Interpretation.
 * 1. create our Spring container
 * 2. Load/associate the Spring container's configuration - in an annotated way
 * 3. complete the Spring container configuration of the creation of beans, dependency injection
 * 4. Create the front-end controller DispatcherServlet and let it hold the Spring container.
 * 5. When the DispatcherServlet holds the container, you can distribute the mapping, please recall our implementation of SpringMVC partners
 * 6. here onStartup is called by Tomcat, and passes the ServletContext object into the
 */
public class MyWebApplicationInitializer implements WebApplicationInitializer {

    public void onStartup(ServletContext)
    public void onStartup(ServletContext servletContext) throws ServletException {
        ("startup...") ;)
        // load Spring web application configuration => container


        AnnotationConfigWebApplicationContext ac = new AnnotationConfigWebApplicationContext(); ; // load Spring web application configuration => container.

        ().
        (); // Finish creating and configuring the bean.

        // 1. Create the front-end controller that is important to register when the DispatcherServlet is created.
        // 2. Let the DispatcherServlet hold the container.
        // 3. This allows for mapping and distribution, recalling the SpringMVC mechanism (implemented by myself)
        DispatcherServlet dispatcherServlet = new DispatcherServlet(ac);

        // Return the object
         registration = ("app", dispatcherServlet); // return the object.

        // When tomcat starts, load the dispatcherServlet
        (1); // When tomcat starts, load the dispatcherServlet.

        // Intercept the request and distribute it
        // Here the instructor is hinting at "/" and "/*", which were used in the instructor's lecture on the java web.
        ("/").

    }
}

在这里插入图片描述

package ;

public class MyMainApp {


    public static void main(String[] args) {
        // activate (a plan)MySpringBoot sports event/programs
        ();
    }
}

3. Finally:

"In this final chapter, I would like to express my gratitude to each and every one of my readers. Your attention and responses have been a source of motivation for me to create, and I have drawn endless inspiration and courage from you. I will keep your encouragement in my heart and continue to struggle in other areas. Thanks to you all, we will always meet again at some point."

在这里插入图片描述