onRefresh()方法执行作用
之前文章跟着代码依然可知,当前系统已加载了所有得bean得定义信息,包括自动配置得类
1、进入方法createEmbeddedServletContainer
private void createEmbeddedServletContainer() {
EmbeddedServletContainer localContainer = this.embeddedServletContainer;
ServletContext localServletContext = getServletContext();
if (localContainer == null && localServletContext == null) {
//获取servlet容器工厂
EmbeddedServletContainerFactory containerFactory = getEmbeddedServletContainerFactory();
//获取servlet容器对象
this.embeddedServletContainer = containerFactory
//getSelfInitializer方法获取初始化对象
.getEmbeddedServletContainer(getSelfInitializer());
}
else if (localServletContext != null) {
try {
getSelfInitializer().onStartup(localServletContext);
}
catch (ServletException ex) {
throw new ApplicationContextException("Cannot initialize servlet context",
ex);
}
}
initPropertySources();
}
2、获取servlet容器工厂
进入getEmbeddedServletContainerFactory();方法
在EmbeddedServletContainerAutoConfiguration配置类中存在容器工厂
3、调用容器工厂得getEmbeddedServletContainer方法
关注后面两行代码
- prepareContext
首先initializers参数是getSelfInitializer方法获取得
protected void prepareContext(Host host, ServletContextInitializer[] initializers) {
File docBase = getValidDocumentRoot();
docBase = (docBase != null ? docBase : createTempDir("tomcat-docbase"));
final TomcatEmbeddedContext context = new TomcatEmbeddedContext();
context.setName(getContextPath());
context.setDisplayName(getDisplayName());
context.setPath(getContextPath());
context.setDocBase(docBase.getAbsolutePath());
context.addLifecycleListener(new FixContextListener());
context.setParentClassLoader(
this.resourceLoader != null ? this.resourceLoader.getClassLoader()
: ClassUtils.getDefaultClassLoader());
resetDefaultLocaleMapping(context);
addLocaleMappings(context);
try {
context.setUseRelativeRedirects(false);
}
catch (NoSuchMethodError ex) {
// Tomcat is < 8.0.30. Continue
}
SkipPatternJarScanner.apply(context, this.tldSkipPatterns);
WebappLoader loader = new WebappLoader(context.getParentClassLoader());
loader.setLoaderClass(TomcatEmbeddedWebappClassLoader.class.getName());
loader.setDelegate(true);
context.setLoader(loader);
if (isRegisterDefaultServlet()) {
addDefaultServlet(context);
}
if (shouldRegisterJspServlet()) {
addJspServlet(context);
addJasperInitializer(context);
context.addLifecycleListener(new StoreMergedWebXmlListener());
}
context.addLifecycleListener(new LifecycleListener() {
@Override
public void lifecycleEvent(LifecycleEvent event) {
if (event.getType().equals(Lifecycle.CONFIGURE_START_EVENT)) {
TomcatResources.get(context)
.addResourceJars(getUrlsOfJarsWithMetaInfResources());
}
}
});
ServletContextInitializer[] initializersToUse = mergeInitializers(initializers);
//配置context
configureContext(context, initializersToUse);
host.addChild(context);
postProcessContext(context);
}
然后进入configureContext(context, initializersToUse);方法
- getTomcatEmbeddedServletContainer
构造方法中会调用初始化方法,启动tomcat
4、tomcat启动,调用onstartup方法
initializer我们关注之前创建得ServletContextInitializer
回调
private void selfInitialize(ServletContext servletContext) throws ServletException {
prepareEmbeddedWebApplicationContext(servletContext);
ConfigurableListableBeanFactory beanFactory = getBeanFactory();
ExistingWebApplicationScopes existingScopes = new ExistingWebApplicationScopes(
beanFactory);
WebApplicationContextUtils.registerWebApplicationScopes(beanFactory,
getServletContext());
existingScopes.restore();
WebApplicationContextUtils.registerEnvironmentBeans(beanFactory,
getServletContext());
for (ServletContextInitializer beans : getServletContextInitializerBeans()) {
beans.onStartup(servletContext);
}
}
看下getServletContextInitializerBeans方法,主要是从beanFactory中获取所有ServletContextInitializer类型得bean,然后调用各自得onStartup方法
这里我们可以看到,对这些类进行了分类,过滤器,监听器在这个时期加入