嵌入式Servlet 启动原理
1)SpringBoot 应用运行run() 方法
public static ConfigurableApplicationContext run(Class<?> primarySource, String... args) {
return run(new Class<?>[] { primarySource }, args);
} |
\|/
|
public static ConfigurableApplicationContext run(Class<?>[] primarySources, String[] args) {
return new SpringApplication(primarySources).run(args);
}
2) run()内
- context = createApplicationContext();
- 【创建IOC对象】
- 如果是web应用 创建AnnotationConfigServletWebServerApplicationContext容器 或者 AnnotationConfigServletWebServerApplicationContext容器
- 否则创建AnnotationConfigApplicationContext 容器
- refreshContext(context);
- 【 刷新IOC容器, 初始化容器,创建容器中的每一个组件】
3) refresh(context); 刷新刚刚创建创建的容器
public void refresh() throws BeansException, IllegalStateException {
synchronized(this.startupShutdownMonitor) {
this.prepareRefresh();
ConfigurableListableBeanFactory beanFactory = this.obtainFreshBeanFactory();
this.prepareBeanFactory(beanFactory);
try {
this.postProcessBeanFactory(beanFactory);
this.invokeBeanFactoryPostProcessors(beanFactory);
this.registerBeanPostProcessors(beanFactory);
this.initMessageSource();
this.initApplicationEventMulticaster();
this.onRefresh();
this.registerListeners();
this.finishBeanFactoryInitialization(beanFactory);
this.finishRefresh();
} catch (BeansException var9) {
if (this.logger.isWarnEnabled()) {
this.logger.warn("Exception encountered during context initialization - cancelling refresh attempt: " + var9);
}
this.destroyBeans();
this.cancelRefresh(var9);
throw var9;
} finally {
this.resetCommonCaches();
}
}
}
4) onRefresh();
- web Ioc 重写了该方法
@Override
protected void onRefresh() {
super.onRefresh();
try {
createWebServer();
}
catch (Throwable ex) {
throw new ApplicationContextException("Unable to start web server", ex);
}
}
5)createWebServer();
- 创建嵌入式Servlet容器
private void createWebServer() {
WebServer webServer = this.webServer;
ServletContext servletContext = getServletContext();
if (webServer == null && servletContext == null) {
ServletWebServerFactory factory = getWebServerFactory();
this.webServer = factory.getWebServer(getSelfInitializer());
}
else if (servletContext != null) {
try {
getSelfInitializer().onStartup(servletContext);
}
catch (ServletException ex) {
throw new ApplicationContextException("Cannot initialize servlet context", ex);
}
}
initPropertySources();
}
6) ServletWebServerFactory factory = getWebServerFactory();
- 获取嵌入式servlet容器工厂
- 从容器中获取ServletWebServerFactory组件
- TomcatServletWebServerFactory创建对象
- 后置处理器进行判断,如果是webServerFactory 类对象,获取所有的Customizer【Customizer对象在此创建】,并调用其customize(),完成servlet相关配置
@Override
public Object postProcessBeforeInitialization(Object bean, String beanName) throws BeansException {
//如果是webServerFactory 类对象,获取所有的Customizer
if (bean instanceof WebServerFactory) {
postProcessBeforeInitialization((WebServerFactory) bean);
}
return bean;
}
private void postProcessBeforeInitialization(WebServerFactory webServerFactory) {
LambdaSafe.callbacks(WebServerFactoryCustomizer.class, getCustomizers(), webServerFactory)
.withLogger(WebServerFactoryCustomizerBeanPostProcessor.class)
.invoke((customizer) -> customizer.customize(webServerFactory));
}
7) this.webServer = factory.getWebServer(getSelfInitializer());
- 使用Servlet 容器工厂 获取嵌入式Servlet 容器
- 嵌入式Servlet 容器 创建对象(此处为tomcat),并启动
public WebServer getWebServer(ServletContextInitializer... initializers) {
return getTomcatWebServer(tomcat);
}
protected TomcatWebServer getTomcatWebServer(Tomcat tomcat) {
return new TomcatWebServer(tomcat, getPort() >= 0);
}
public TomcatWebServer(Tomcat tomcat, boolean autoStart) {
Assert.notNull(tomcat, "Tomcat Server must not be null");
this.tomcat = tomcat;
this.autoStart = autoStart;
initialize();
}
private void initialize() throws WebServerException {
this.tomcat.start();
}
8)先启动嵌入式的Servlet容器,再将Ioc容器中没有创建的对象获取出来