SpingWebInitializer的加载
Spring基于注解的配置代码:
public class SpingWebInitializer extends AbstractAnnotationConfigDispatcherServletInitializer {
@Override
protected Class<?>[] getRootConfigClasses() {
return new Class<?>[]{RootConfig.class};
}
@Override
protected Class<?>[] getServletConfigClasses() {
return new Class<?>[]{WebConfig.class};
}
@Override
protected String[] getServletMappings() {
return new String[]{"/"};
}
}
整体调用UML图:
SpringServletContainerInitializer.onStartup传入参数:
类型判断必须是继承WebApplicationInitializer接口:
isAssignableFrom 是用来判断一个类Class1和另一个类Class2是否相同或是另一个类的超类或接口。
通常调用格式是
Class1.isAssignableFrom (Class2)
调用者和参数都是 java.lang.Class 类型。
而 instanceof 是用来判断一个对象实例是否是一个类或接口的或其子类子接口的实例。
格式是: oo instanceof TypeName
第一个参数是对象实例名,第二个参数是具体的类名或接口名
参考:Class.isAssignableFrom与 instanceof 区别
List<WebApplicationInitializer> initializers:
onStartup()调用链:
AbstractDispatcherServletInitializer 有onStartup()
->AbstractAnnotationConfigDispatcherServletInitializer 无onStartup()
->SpingWebInitializer 无onStartup()
调用父类的AbstractContextLoaderInitializer的onStartup()
调用createRootApplicationContext()
createRootApplicationContext()调用链:
AbstractAnnotationConfigDispatcherServletInitializer有createRootApplicationContext()
->AbstractDispatcherServletInitializer无createRootApplicationContext()
->AbstractContextLoaderInitializer调用createRootApplicationContext()
继承的调用链是逐级往下逐级往上
终于调用到getRootConfigClasses()开始第一阶段
register就是往set集合增加类
public void register(Class<?>... annotatedClasses) {
Assert.notEmpty(annotatedClasses, "At least one annotated class must be specified");
this.annotatedClasses.addAll(Arrays.asList(annotatedClasses));
}
回到registerContextLoaderListener
ContextLoaderListener
ContextLoader
返回ContextLoaderListener
调用tomcat的ApplicationContextFacade implements ServletContext 调用addListener
调用addListener
addApplicationLifecycleListener
applicationLifecycleListenersObjects
newListeners
回到registerContextLoaderListener
完成onStartup
进入registerDispatcherServlet
调用createServletApplicationContext
开始第二阶段进入SpingWebInitializer的getServletConfigClasses
register同第一阶段
回到registerDispatcherServlet
进入tomcat的ApplicationContextFacade addServlet
addServlet
addChild
super.addChild
addChildInternal
children
回到registerDispatcherServlet
第三次进入SpingWebInitializer
回到registerDispatcherServlet
回到onStartup
回到onStartup
退出到Tomcat的StandardContext的startInternal()
entry.getKey()
initializers