基本流程图
![](https://img.haomeiwen.com/i26273155/113cd7a7d5a592e0.png)
TomcatServletWebServerFactory的getWebServer
前面我们获取到了TomcatServletWebServerFactory
,现在就要创建了,创建TomcatWebServer
,里面会进行初始化,这里的方法就不多讲了,是关于tomcat
的一些组件的设置和启动,有兴趣可以自己研究下,我们重点关注springmvc
这边的。
@Override
public WebServer getWebServer(ServletContextInitializer... initializers) {
if (this.disableMBeanRegistry) {
Registry.disableRegistry();
}
Tomcat tomcat = new Tomcat();
File baseDir = (this.baseDirectory != null) ? this.baseDirectory : createTempDir("tomcat");
tomcat.setBaseDir(baseDir.getAbsolutePath());
Connector connector = new Connector(this.protocol);
connector.setThrowOnFailure(true);
tomcat.getService().addConnector(connector);
customizeConnector(connector);
tomcat.setConnector(connector);
tomcat.getHost().setAutoDeploy(false);
configureEngine(tomcat.getEngine());
for (Connector additionalConnector : this.additionalTomcatConnectors) {
tomcat.getService().addConnector(additionalConnector);
}
prepareContext(tomcat.getHost(), 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();
}
ServletWebServerApplicationContext的finishRefresh
完成刷新后,就启动了服务器,并发出ServletWebServerInitializedEvent
事件:
![](https://img.haomeiwen.com/i26273155/62c598783c42f913.png)
![](https://img.haomeiwen.com/i26273155/613cfba5af0b56ff.png)
DispatcherServlet初始化
流程图参考
![](https://img.haomeiwen.com/i26273155/d0ea38c407fa6fd2.png)
第一次来请求的时候会进行初始化,调用initStrategies
方法,其实就是把需要的组件都获取到:
protected void initStrategies(ApplicationContext context) {
initMultipartResolver(context);//上传文件
initLocaleResolver(context);//本地化
initThemeResolver(context);//主题
initHandlerMappings(context);//映射器
initHandlerAdapters(context);//处理器适配器
initHandlerExceptionResolvers(context);//异常处理
initRequestToViewNameTranslator(context);//视图名转换
initViewResolvers(context);//视图解析
initFlashMapManager(context);//重定向保存数据
}
内部其实很多都是一样的形式,我拿两个分析下:
initMultipartResolver
首先会获取名字为multipartResolver
的实例,如果不存在就为null
。
public static final String MULTIPART_RESOLVER_BEAN_NAME = "multipartResolver";
private void initMultipartResolver(ApplicationContext context) {
try {
this.multipartResolver = context.getBean(MULTIPART_RESOLVER_BEAN_NAME, MultipartResolver.class);
if (logger.isTraceEnabled()) {
logger.trace("Detected " + this.multipartResolver);
}
else if (logger.isDebugEnabled()) {
logger.debug("Detected " + this.multipartResolver.getClass().getSimpleName());
}
}
catch (NoSuchBeanDefinitionException ex) {
// Default is no multipart resolver.
this.multipartResolver = null;
if (logger.isTraceEnabled()) {
logger.trace("No MultipartResolver '" + MULTIPART_RESOLVER_BEAN_NAME + "' declared");
}
}
}
![](https://img.haomeiwen.com/i26273155/43a3328c2e1c9f3b.png)
这个自动配置的时候有注册,具体在MultipartAutoConfiguration
中。
![](https://img.haomeiwen.com/i26273155/e21616f62b00c445.png)
网友评论