SpringBoot (3) WebServerApplicationContext
SpringBoot版本
SpringBoot 2.1.6
WebServerApplicationContext
在run方法中,通过反射创建了AnnotationConfigServletWebServerApplicationContext
public ConfigurableApplicationContext run(String... args) {
...
ConfigurableApplicationContext context = null;
...
try {
...
context = createApplicationContext();
...
prepareContext(context, environment, listeners, applicationArguments, printedBanner);
refreshContext(context);
afterRefresh(context, applicationArguments);
...
}
catch (Throwable ex) {
...
}
...
return context;
}
prepareContext
准备context的环境,应用相关的后置处理器,调用ApplicationContextInitializer
的initialize初始化 ,加载资源,加载相关bean
refreshContext
refreshContext使用了refresh,调用了AbstractApplicationContext
的refresh
private void refreshContext(ConfigurableApplicationContext context) {
refresh(context);
if (this.registerShutdownHook) {
try {
context.registerShutdownHook();
}
catch (AccessControlException ex) {
// Not allowed in some environments.
}
}
}
refresh属于Spring framework中的操作
通过ConfigurationClassPostProcessor
来扫描注解@ComponentScan,@Import(AutoConfigurationImportSelector)
创建server
在创建了AnnotationConfigServletWebServerApplicationContext
后的refresh过程中OnRefresh,创建了WebServer
@Override
protected void onRefresh() {
super.onRefresh();
try {
createWebServer();
}
catch (Throwable ex) {
throw new ApplicationContextException("Unable to start web server", ex);
}
}
通过ServletWebServerFactory创建了WebServer,在通过ServletContextInitializer 的接口做init。
public interface ServletContextInitializer {
/**
* Configure the given {@link ServletContext} with any servlets, filters, listeners
* context-params and attributes necessary for initialization.
* @param servletContext the {@code ServletContext} to initialize
* @throws ServletException if any call against the given {@code ServletContext}
* throws a {@code ServletException}
*/
void onStartup(ServletContext servletContext) throws ServletException;
}
启动server
重写了finishRefresh,开始启动server
@Override
protected void finishRefresh() {
super.finishRefresh();
WebServer webServer = startWebServer();
if (webServer != null) {
publishEvent(new ServletWebServerInitializedEvent(webServer, this));
}
}
小结
ApplicationContext的类型是可以通过参数控制,但是常用的也就是web和非web,还有一种是Reactive
,可以看出SpringBoot完全是靠注解走遍所有流程,文中已经省略了涉及的Spring框架,如果觉得不明白,还是去先看明白Spring框架,再看这篇水文。
通过对Spring框架的扩展,SpringBoot在执行过程中context有了,servlet也有了,我们所需要的资源都ok了。
OK,又水一篇
key word
AnnotationConfigServletWebServerApplicationContext
主目录