Springboot 2 Tomcat using an external source analysis

Springboot using an external Tomcat

1. Modify the pom.xml, instead playing war Pack
<packaging>war</packaging>
2. Springboot built tomcat scope changedprovided

<dependency>
    <groupId>org.springframework.boot</groupId>
    <artifactId>spring-boot-starter-tomcat</artifactId>
    <scope>provided</scope>
</dependency>

3. Rewrite SpringBootServletInitializer

@SpringBootApplication
public class Bootstrap extends SpringBootServletInitializer {
  public static void main(String[] args) {
    SpringApplication.run(Bootstrap.class, args);
  }

  @Override
  protected SpringApplicationBuilder configure(SpringApplicationBuilder builder) {
    return builder.sources(Bootstrap.class);
  }
}

After the war 4.maven packing bag, put it to the webapps directory of tomcat.

Interface To access the war package, the default url need to add the project name as a prefix, for example: http: // localhost: 8080 / {project name} / users / 123456

Principle Analysis

ServletContainerInitializer

When the Servlet container starts, it scans the current application path of each jar package META-INF\servicesfiles in javax.servlet.ServletContainerInitializerits file contents is ServletContainerInitializer implementation class full class name, and call its onStartup () method. For example, in the Spring-web package, the contents of the file is org.springframework.web.SpringServletContainerInitializer, its source code is as follows:

// 容器启动时,将 WebApplicationInitializer 的所有子类传递至 webAppInitializerClasses
@HandlesTypes(WebApplicationInitializer.class)
public class SpringServletContainerInitializer implements ServletContainerInitializer {
    /**
     * @param webAppInitializerClasses @HandlesTypes 导入的类
     * @param servletContext 当前 web 应用 servlet 上下文
     */
    @Override
    public void onStartup(@Nullable Set<Class<?>> webAppInitializerClasses, ServletContext servletContext) throws ServletException {
        List<WebApplicationInitializer> initializers = new LinkedList<>();
        for (Class<?> waiClass : webAppInitializerClasses) {
            // 过滤出可用的 WebApplicationInitializer
            if (!waiClass.isInterface() && !Modifier.isAbstract(waiClass.getModifiers()) && WebApplicationInitializer.class.isAssignableFrom(waiClass)) {
                initializers.add((WebApplicationInitializer)ReflectionUtils.accessibleConstructor(waiClass).newInstance());
            }
        }
        for (WebApplicationInitializer initializer : initializers) {
            initializer.onStartup(servletContext);
        }
    }
}

When the container is started, execution SpringServletContainerInitializer.onStartup () method, @ HandlesTypes annotation declares that all subclasses WebApplicationInitializer (in the previous example, class start Bootstrap implemented SpringBootServletInitializer is its realization a) is passed to the parameter webAppInitializerClasses method.

OnStartup () method filters out webAppInitializerClasses available on Bootstrap WebApplicationInitializer subclasses, then the callback SpringBootServletInitializer of OnStartup () method, the following source code:

public void onStartup(ServletContext servletContext) throws ServletException {
    WebApplicationContext rootAppContext = createRootApplicationContext(servletContext);
}
protected WebApplicationContext createRootApplicationContext(ServletContext servletContext) {
    SpringApplicationBuilder builder = createSpringApplicationBuilder();
    // 指定主类 Bootstrap
    builder.main(getClass());
    // 回调 Bootstrap 重写的方法
    builder = configure(builder);
    return run(builder.build());
}

This method configures the current web application context: Specify the main class, registered servletContext, call configure (), run run.

Since rewriting Configure Bootstrap (), so the method will perform rewriting to specify the main class, and finally accomplished by the application start Springboot run.

Guess you like

Origin www.cnblogs.com/bigshark/p/11367140.html