开发者学堂课程【SpringBoot快速掌握 - 核心技术:外部 Servlet 容器启动】学习笔记,与课程紧密联系,让用户快速学习知识。
课程地址:https://developer.aliyun.com/learning/course/612/detail/9264
外部 Servlet 容器启动
内容介绍
一、原理
二、核心
一、原理
Jar包:执行 SpringBoot 主类的 main 方法,启动 IOC 容器,创建 Servlet 容器;
War包:启动服务器,服务器启动 SpringBoot 应用【SpringBootServletnitializer】,启动 ioc 容器;
servlet3.0 ( Spring 注解版)︰
8.2.4 Shared libraries / runtimes pluggability :
1.规则∶
1 )服务器启动( web 应用启动)会创建当前 web 应用里面每一个jar包里面ServletContainerInitializer实例︰
2)ServletContainerInitializer 的实现放在 jar 包的META-INF/services 文件夹下,有一个名为javax.servlet.ServletContainerlnitializer的文件,内容就是ServletContainerInitializer 的实现类的全类名
3 )、还可以使用 @HandlesTypes,在应用启动的时候加载我们感兴趣的类;
2.流程︰
1)、启动 Tomcat
2),org\springframeworklspring-web14.3.14.RELEASEIspring-web-
4.3.14.RELEASE.jarI\META-INFlservicesljavax.servlet.ServletContainerlnitializer
3 ) 、SpringServletContainerInitializer 将@HandlesTypes(WebApplicationInitializer.class)标注的所有这个类型的类都传入到onStartup 方法的Set>
;为这些WebApplicationInitializer 类型的类创建实例;
4)、每一个WebApplicationlnitializer 都调用自己的 onStartup ;
5)、相当于我们的 SpringBootServletInitializer 的类会被创建对象,并执行 onStartup 方法
6 ) 、SpringBootServletlnitializer 示例执行 onStartup 的时候会 createRootApplicationContext ;创建容器
protected webApplicationcontext createRootApplicationContext(
Servletcontext servletcontext) {
//1、创建 SpringApplicationBuilder
SpringApplicationBuilder
//调用 configure 方法,子类重写了这个方法,将 SpringBoot的主程序类传入了进来
builder = createSpringApplicationBuilder();
//使用 builder 创建一个 Spring 应用
StandardServletEnvironment environment = new StandardServletEnvironment();
environment.initPropertySources(servletcontext, null);
builder.environment(environment);
builder.main(getclass());
ApplicationContext parent = getExistingRootwebApplicationContext(servletContext);if (parent != null){
this.logger.info("Root context already created (using as parent). ");servletcontext.setAttribute(
webApplicationcontext.ROOT_wEB_APPLICATION_CONTEXT_ATTRIBUTE, null);
builder.initializers(new ParentContextApplicationContextInitializer(parent));}
builder.initializers(
new ServletContextApplicationContextInitializer(servletContext));builder.contextClass(AnnotationConfigEmbeddedwebApplicationContext.class);builder = configure(builder);
SpringApplication application = builder.build();
if (application.getSources().isEmpty() && Annotationutils
.findAnnotation(getclass(),configuration.class) != null){application.getSources().add(getclass());
}
if (application.getsources().isEmpty() && Annotationutils
.findAnnotation(getclass(), configuration.class) != null){application.getSources().add(getclass());
Assert.state(!application.getSources ().isEmpty(),
"No SpringApplication sources have been defined. Either override the"
+ "configure method or add an @Configuration annotation");
// Ensure error pages are registered
if(this.registerErrorPageFilter) {
application.getSources ().add(ErrorPageFilterConfiguration.class);}
//启动 Spring 应用
return run(application);
}
7) 、Spring 的应用就启动并且创建 IOC 容器
public configurableApplicationContext run(String... args){
Stopwatch stoplwatch = new Stopwatch();
stopwatch.start();
ConfigurableApplicationcontext context =null;FailureAnalyzers analyzers = null;
configureHeadles sProperty();
SpringApplicationRunListeners listeners = getRunListeners(args);listeners.starting();
try {
ApplicationArguments = new DefaultApplicationArguments(
args);
ConfigurableEnvironment environment = prepareEnvironment(listeners,
applicationArguments);
Banner printedBanner = printBanner(environment);context = createApplicationcontext();
analyzers = new FailureAnalyzers( context);
prepareContext(context,environment, listeners, applicationArguments,
printedBanner);
//刷新 IOC 容器
refreshContext(context);
afterRefresh(context,applicationArguments);listeners.finished(context,null);
stoplatch.stop();
if (this.logStartupInfo){
new StartupInfoLogger(this.mainApplicationclass)
. logStarted(getApplicationLog(),stoplatch);
}
return context;}
catch (Throwable ex){
handleRunFailure(context, listeners,analyzers,ex);throw new IllegalstateException(ex);
}
二、核心
1、SpringBootServletlnitializer– 重写 configure
2、SpringApplicationBuilder
- builder.source(@SpringBootApplication类)
3、启动原理
一Servlet3.0 标准 ServletContainerlnitializer 扫描所有 jar 包中META-
INF/services/javax.servlet.ServletContainerlnitializer
文件指定的类并加载
一 加载 spring web 包下的 SpringServletContainerlnitializer
一 扫描 @HandleType(WebApplicationInitializer)
一 加载SpringBootServletlnitializer
并运行 onStartup 方法+
一 加载 @SpringBootApplication
主类,启动容器等