spring boot war started is the use of Servlet 3.0 new ServletContainerInitializer interface implementation.
Main logic
-
Spring in the spring-web-version.jar / META-INF / services / javax.servlet.ServletContainerInitializer document, disposed on a spring org.springframework.web.SpringServletContainerInitializer ServletContainerInitializer implementation class interface.
-
Servlet Container scanning start phase jar package META-INF / services / javax.servlet.ServletContainerInitializer file, obtaining ServletContainerInitializer implementation class and instantiated, the analytic ServletContainerInitializer @HandlesTypes annotation, to find out the type of collection @HandlesTypes defined as ServletContainerInitializer. OnStartup Method the first process parameter c.
-
Servlet Container in turn calls onStartup each ServletContainerInitializer instance. Scene war package calls initiated in SpringServletContainerInitializer.onStartup, the method set for each cycle is called c WebApplicationInitializer subclass (i.e. SpringBootServletInitializer) of onStartup method.
-
SpringBootServletInitializer.onStartup method calls SpringBootServletInitializer.createRootApplicationContext method, createRootApplicationContext method SpringApplication build and execute the entire spring SpringApplication.run method to initiate the project.
Source
Spring's implementation class ServletContainerInitializer
@HandlesTypes(WebApplicationInitializer.class) public class SpringServletContainerInitializer implements ServletContainerInitializer { ...... @Override public void onStartup(@Nullable Set<Class<?>> webAppInitializerClasses, ServletContext servletContext) throws ServletException { List<WebApplicationInitializer> initializers = new LinkedList<>(); if (webAppInitializerClasses != null) { for (Class<?> waiClass : webAppInitializerClasses) { // Be defensive: Some servlet containers provide us with invalid classes, // no matter what @HandlesTypes says... if (!waiClass.isInterface() && !Modifier.isAbstract(waiClass.getModifiers()) && WebApplicationInitializer.class.isAssignableFrom(waiClass)) { try { initializers.add((WebApplicationInitializer)ReflectionUtils.accessibleConstructor(waiClass).newInstance()); } catch (Throwable ex) { throw new ServletException("Failed to instantiate WebApplicationInitializer class", ex); } } } } if (initializers.isEmpty()) { servletContext.log("No Spring WebApplicationInitializer types detected on classpath"); return; } servletContext.log(initializers.size() + " Spring WebApplicationInitializers detected on classpath"); AnnotationAwareOrderComparator.sort(initializers); for (WebApplicationInitializer initializer : initializers) { initializer.onStartup(servletContext); } } }
Interface implementation class WebApplicationInitializer.class
public abstract class SpringBootServletInitializer implements WebApplicationInitializer { ...... @Override public void onStartup(ServletContext servletContext) throws ServletException { // Logger initialization is deferred in case an ordered // LogServletContextInitializer is being used this.logger = LogFactory.getLog(getClass()); WebApplicationContext rootAppContext = createRootApplicationContext(servletContext); ......//略去部分代码 } protected WebApplicationContext createRootApplicationContext( ServletContext servletContext) { SpringApplicationBuilder builder = createSpringApplicationBuilder(); builder.main(getClass()); ApplicationContext parent = getExistingRootWebApplicationContext(servletContext); ......//略去部分代码 return run(application); } protected WebApplicationContext run(SpringApplication application) { return (WebApplicationContext) application.run(); } }
spring boot main application class
@SpringBootApplication public class Application extends SpringBootServletInitializer { public static void main(String[] args) { SpringApplication.run(Application.class, args); } }