初始化
tomcat会读取web.xml,从里面获取servlet class得到DispatcherServlet,父类是HttpServlet,有doget,dopost,传入request,传出response。
tomcat在开始的时候会调用HttpServlet的init方法,子类重写这个方法。FrameworkServlet继承HttpServlet,增加WebApplicationContext。
DispatcherServlet继承FrameworkServlet,增加HandlerMapping和handlerAdapters。
最开始首先创建WebApplicationContext。
public void refresh() throws BeansException, IllegalStateException {
synchronized (this.startupShutdownMonitor) {
// Tell the subclass to refresh the internal bean factory.
ConfigurableListableBeanFactory beanFactory = obtainFreshBeanFactory();
prepareBeanFactory(beanFactory);
// Register bean processors that intercept bean creation.
registerBeanPostProcessors(beanFactory);
finishBeanFactoryInitialization(beanFactory);
}
}
在obtainFreshBeanFactory的loadBeanDefinitions,会调用getDefaultConfigLocation,Namespace就是xml配置的servlet-name,读取的就是dispatcher-servlet.xml。
protected String getDefaultConfigLocation() {
if (getNamespace() != null) {
return DEFAULT_CONFIG_LOCATION_PREFIX + getNamespace() + DEFAULT_CONFIG_LOCATION_SUFFIX;
}
else {
return DEFAULT_CONFIG_LOCATION;
}
}
这里对beanfactory进行BeanDefinition注册。
else if(namespaceUri.equals("http://www.springframework.org/schema/context")&& ele.getLocalName().equals("component-scan")){
//找出需要搜索的包,并注册controller
NamespaceHandler namespaceHandler=this.namespaceHandlers.get(namespaceUri);
namespaceHandler.parse(ele,this.registry);
}
else if(namespaceUri.equals("http://www.springframework.org/schema/mvc") && ele.getLocalName().equals("annotation-driven")){
BeanDefinition handlerMappingDef = null;
try {
handlerMappingDef = new BeanDefinition(HANDLER_MAPPING_BEAN_NAME);
} catch (ClassNotFoundException e) {
e.printStackTrace();
}
this.registry.registerBeanDefinition(HANDLER_MAPPING_BEAN_NAME , handlerMappingDef);
BeanDefinition handlerAdapterDef = null;
try {
handlerAdapterDef = new BeanDefinition(HANDLER_ADAPTER_BEAN_NAME);
} catch (ClassNotFoundException e) {
e.printStackTrace();
}
this.registry.registerBeanDefinition(HANDLER_ADAPTER_BEAN_NAME , handlerAdapterDef);
}
module不能循环依赖,怎么互相使用对方的类呢?
通过反射
NamespaceHandlerSupport
这个类提供了基本的解析功能,由子类实现init方法来注册parser。
context:component-scan
扫描对应的包,读取类信息,注册beandefinition
public Set<BeanDefinitionHolder> doScan(String... basePackages) {
Set<BeanDefinitionHolder> beanDefinitions = new