微服务架构Day05-SpringBoot之Servlet (3)

servlet3.0的8.2.4 Shared libraries / runtimes pluggability中的规则:
1.服务器启动(web应用启动)会创建当前web应用里面每一个jar包里面ServletContainerInitializer实例
2.ServletContainerInitializer的实现放在jar包的META-INF/services文件夹下,有一个javax.servlet.ServletContainerInitializer的文件,内容是ServletContainerInitializer实现类的全类名
3.可以使用 @HandleTypes注解,在应用启动时加载需要的类
流程:
1.启动Tomcat
2.

org\springframework\spring-web\5.1.9.RELEASE\spring-web-5.1.9.RELEASE.jar\META-INF\services\javax.servlet.ServletContainerInitializer

Spring的web模块中有这个文件:org.springframework.web.SpringServletContainerInitializer
3.SpringServletContainerInitializer将@HandleTypes({WebApplicationInitializer.class})标注的所有类型的类都传入到onStartup方法的Set<Class<?>>中,为WebApplicationInitializer类型的类创建实例
4.每一个WebApplicationInitializer都调用自己的onStartup方法启动
5.SpringBootServletInitializer类会创建对象并执行onStartup方法启动
6.SpringBootServletInitializer执行onStartup方法会调用createRootApplicationContext创建容器

protected WebApplicationContext createRootApplicationContext(ServletContext servletContext) { // 创建SpringApplicationBuilder构建器 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)}); } builder.initializers(new ApplicationContextInitializer[]{new ServletContextApplicationContextInitializer(servletContext)}); builder.contextClass(AnnotationConfigServletWebServerApplicationContext.class); // 调用configure方法,子类重写该方法,将SpringBoot的主程序类传入进来 builder = this.configure(builder); builder.listeners(new ApplicationListener[]{new SpringBootServletInitializer.WebEnvironmentPropertySourceInitializer(servletContext)}); // 使用builder创建一个Spring应用 SpringApplication application = builder.build(); if (application.getAllSources().isEmpty() && AnnotationUtils.findAnnotation(this.getClass(), Configuration.class) != null) { application.addPrimarySources(Collections.singleton(this.getClass())); } Assert.state(!application.getAllSources().isEmpty(), "No SpringApplication sources have been defined. Either override the configure method or add an @Configuration annotation"); if (this.registerErrorPageFilter) { application.addPrimarySources(Collections.singleton(ErrorPageFilterConfiguration.class)); } // 启动Spring应用 return this.run(application); }

7.Spring就启动成功,并且创建IOC容器

protected WebApplicationContext run(SpringApplication application) { return (WebApplicationContext)application.run(new String[0]); }

先启动Servlet容器,再启动SpringBoot应用

内容版权声明:除非注明,否则皆为本站原创文章。

转载注明出处:https://www.heiqu.com/wsxwgf.html