延伸阅读:Spring Boot启动MVC的流程
main
启动
SpringApplication
1
public ConfigurableApplicationContext run(String... args)
try { //准备环境,并确认classpath是否拥有web环境 ConfigurableEnvironment environment = this.prepareEnvironment(listeners, applicationArguments); //... //根据当前环境创建Spring应用上下文 //web的则为(此处应为)o.s.b.c.e.AnnotationConfigEmbeddedWebApplicationContext //普通则为o.s.c.a.AnnotationConfigApplicationContext context = this.createApplicationContext(); //... //刷新Spring应用上下文--->2 this.refreshContext(context); //... } catch (Throwable var9) { //.. }
2
private void refreshContext(ConfigurableApplicationContext context)
private void refreshContext(ConfigurableApplicationContext context) {
this.refresh(context);
if (this.registerShutdownHook) {
try {
context.registerShutdownHook();
} catch (AccessControlException var3) {
;
}
}
}
- 3
protected void refresh(ApplicationContext applicationContext)
protected void refresh(ApplicationContext applicationContext) {
// 判断是否是AbstractApplicationContext的实例
Assert.isInstanceOf(AbstractApplicationContext.class, applicationContext);
// 上转,此处执行的是AnnotationConfigEmbeddedWebApplicationContext的父类的refresh
((AbstractApplicationContext)applicationContext).refresh();
}
EmbeddedWebApplicationContext
- 1 执行父类
AbstractApplicationContext
的refresh()
,再该方法中执行到this.onRefresh();
,再返回EmbeddedWebApplicationContext
的onRefresh()
protected void onRefresh() {
super.onRefresh();
try {
//创建嵌入式servlet容器
this.createEmbeddedServletContainer();
} catch (Throwable var2) {
throw new ApplicationContextException("Unable to start embedded container", var2);
}
}
- 2
private void createEmbeddedServletContainer()
private void createEmbeddedServletContainer() {
//...
if (localContainer == null && localServletContext == null) {
//auto-configuration 已经给你配置好了EmbeddedServletContainerFactory
//默认使用Tomcat,则containerFactory为TomcatEmbeddedServletContainerFactory
EmbeddedServletContainerFactory containerFactory = this.getEmbeddedServletContainerFactory();
//此处传入一个只有一个o.s.b.w.s.ServletContextInitializer实现的内部类
//ServletContextInitializer是用来配置ServletContext的
this.embeddedServletContainer = containerFactory.getEmbeddedServletContainer(new ServletContextInitializer[]{this.getSelfInitializer()});
}
//...
}
private ServletContextInitializer getSelfInitializer() {
return new ServletContextInitializer() {
public void onStartup(ServletContext servletContext) throws ServletException {
EmbeddedWebApplicationContext.this.selfInitialize(servletContext);
}
};
}
TomcatEmbeddedServletContainerFactory
由
EmbeddedServletContainerAutoConfiguration
提供实例化
- 1
public EmbeddedServletContainer getEmbeddedServletContainer(ServletContextInitializer... initializers)
、
public EmbeddedServletContainer getEmbeddedServletContainer(ServletContextInitializer... initializers) {
/*配置tomcat,容器是层次结构的,最外层是tomcat,然后是server->service->host*/
/*Server为StandardServer Service为StandardService Host为StandardHost*/
Tomcat tomcat = new Tomcat();
File baseDir = this.baseDirectory != null ? this.baseDirectory : this.createTempDir("tomcat");
tomcat.setBaseDir(baseDir.getAbsolutePath());
Connector connector = new Connector(this.protocol);
tomcat.getService().addConnector(connector);
this.customizeConnector(connector);
tomcat.setConnector(connector);
tomcat.getHost().setAutoDeploy(false);
this.configureEngine(tomcat.getEngine());
Iterator var5 = this.additionalTomcatConnectors.iterator();
while(var5.hasNext()) {
Connector additionalConnector = (Connector)var5.next();
tomcat.getService().addConnector(additionalConnector);
}
/*配置tomcat结束*/
this.prepareContext(tomcat.getHost(), initializers);
return this.getTomcatEmbeddedServletContainer(tomcat);
}
- 2
protected void prepareContext(Host host, ServletContextInitializer[] initializers)
protected void prepareContext(Host host, ServletContextInitializer[] initializers) {
/*配置context,相当于server.xml文件中<engine>-><host>-><context>节点*/
File docBase = this.getValidDocumentRoot();
docBase = docBase != null ? docBase : this.createTempDir("tomcat-docbase");
//注意 context类型为 TomcatEmbeddedContext
final TomcatEmbeddedContext context = new TomcatEmbeddedContext();
context.setName(this.getContextPath());
context.setDisplayName(this.getDisplayName());
context.setPath(this.getContextPath());
context.setDocBase(docBase.getAbsolutePath());
context.addLifecycleListener(new FixContextListener());
context.setParentClassLoader(this.resourceLoader != null ? this.resourceLoader.getClassLoader() : ClassUtils.getDefaultClassLoader());
this.resetDefaultLocaleMapping(context);
this.addLocaleMappings(context);
//...
/**配置context结束*/
//将传入的ServletContextInitializer(EmbeddedWebApplicationContext的一个匿名内部类)与初始化TomcatEmbeddedServletContainerFactory时传入的ServletContextInitializer进行整合(ServerProperties.SessionConfiguringInitializer和InitParameterConfiguringServletContextInitializer)
// 以上两个ServletContextInitializer来自于ServerProperties,
// ServerProperties的bean由ServerPropertiesAutoConfiguration自动产生,由于ServerProperties实现了EmbeddedServletContainerCustomizer接口,内部的customize方法将由IoC框架执行
ServletContextInitializer[] initializersToUse = this.mergeInitializers(initializers);
//调用下文---->3
this.configureContext(context, initializersToUse);
//context配置完后,添加到host的子中
host.addChild(context);
this.postProcessContext(context);
}
protected final ServletContextInitializer[] mergeInitializers(ServletContextInitializer... initializers) {
List<ServletContextInitializer> mergedInitializers = new ArrayList();
mergedInitializers.addAll(Arrays.asList(initializers));
mergedInitializers.addAll(this.initializers);
return (ServletContextInitializer[])mergedInitializers.toArray(new ServletContextInitializer[mergedInitializers.size()]);
}
3
protected void configureContext(Context context, ServletContextInitializer[] initializers)
protected void configureContext(Context context, ServletContextInitializer[] initializers) { //创建一个TomcatStarter来包裹ServletContextInitializer //TomcatStarter实现了ServletContainerInitializer接口 //以后会在其onStartup中调用ServletContextInitializer的onStartup //相当于容器的初始化器,会初始化ServletContext TomcatStarter starter = new TomcatStarter(initializers); //将容器的初始化器TomcatStarter 添加给TomcatEmbeddedContext(server.xml里的<context>,对应一个应用) context.addServletContainerInitializer(starter, NO_CLASSES); //做更详细的配置 }
4
protected TomcatEmbeddedServletContainer getTomcatEmbeddedServletContainer(Tomcat tomcat)
执行完3后,一层层返回,最后回到1,然后调用4这个方法
protected TomcatEmbeddedServletContainer getTomcatEmbeddedServletContainer(Tomcat tomcat) {
return new TomcatEmbeddedServletContainer(tomcat, this.getPort() >= 0);
}
TomcatEmbeddedServletContainer
- 1
public TomcatEmbeddedServletContainer(Tomcat tomcat, boolean autoStart)
调用构造函数 - 2
private void initialize() throws EmbeddedServletContainerException
构造函数内,执行了此方法
private void initialize() throws EmbeddedServletContainerException {
//这一步算是完成了tomcat的初始化了
logger.info("Tomcat initialized with port(s): " + this.getPortsDescription(false));
Object var1 = this.monitor;
synchronized(this.monitor) {
try {
this.addInstanceIdToEngineName();
try {
this.removeServiceConnectors();
//启动tomcat
this.tomcat.start();
this.rethrowDeferredStartupExceptions();
Context context = this.findContext();
try {
ContextBindings.bindClassLoader(context, this.getNamingToken(context), this.getClass().getClassLoader());
} catch (NamingException var5) {
;
}
this.startDaemonAwaitThread();
} catch (Exception var6) {
containerCounter.decrementAndGet();
throw var6;
}
} catch (Exception var7) {
throw new EmbeddedServletContainerException("Unable to start embedded Tomcat", var7);
}
}
}
StandardServer StandardService StandardEngine
依次调用StandardServer.start()
->LifecycleBase.start()
->StandardServer.startInternal()
-> StandardService.start()
->LifecycleBase.start()
->StandardService.startInternal()
-> StandardService.start()
->LifecycleBase.start()
->StandardService.startInternal()
-> StandardEngine.start()
->LifecycleBase.start()
->StandardEngine.startInternal()
->ContainerBase.startInternal()
- 1
ContainerBase.startInternal()
protected synchronized void startInternal() throws LifecycleException {
Container[] children = this.findChildren();
//...
//children 为StandardEngine的children ,当前只有一个StandardHost
Container[] children = this.findChildren();
List<Future<Void>> results = new ArrayList();
//为每个host启动一个进程,使用future模型,可以回掉的
for(int i = 0; i < children.length; ++i) {
results.add(this.startStopExecutor.submit(new ContainerBase.StartChild(children[i])));
}
boolean fail = false;
Iterator i$ = results.iterator();
while(i$.hasNext()) {
Future result = (Future)i$.next();
try {
//启动future,调用StandardHost的start方法
result.get();
} catch (Exception var9) {
log.error(sm.getString("containerBase.threadedStartFailed"), var9);
fail = true;
}
}
//...
}
-> StandardHost.start()
->LifecycleBase.start()
->StandardHost.startInternal()
->ContainerBase.startInternal()
同理启动-> TomcatEmbeddedContext .start()
->LifecycleBase.start()
->TomcatEmbeddedContext .startInternal()
- 2
TomcatEmbeddedContext protected synchronized void startInternal() throws LifecycleException
protected synchronized void startInternal() throws LifecycleException {
//...
/*挨个启动之前放在TomcatStart里的ServletContainerInitializer*/
Iterator i$ = this.initializers.entrySet().iterator();
while(i$.hasNext()) {
Entry entry = (Entry)i$.next();
try {
((ServletContainerInitializer)entry.getKey()).onStartup((Set)entry.getValue(), this.getServletContext());
} catch (ServletException var22) {
log.error(sm.getString("standardContext.sciFail"), var22);
ok = false;
break;
}
}
//...
}
综上完成全部内容