<?xml version="1.0" encoding="UTF-8"?>
<web-app id="starter" version="2.4" xmlns="http://java.sun.com/xml/ns/j2ee"
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xsi:schemaLocation="http://java.sun.com/xml/ns/j2ee http://java.sun.com/xml/ns/j2ee/web-app_2_4.xsd">
<context-param>
<param-name>contextConfigLocation</param-name>
<param-value>classpath:spring-config.xml</param-value>
</context-param>
<servlet>
<servlet-name>spring</servlet-name>
<servlet-class>org.springframework.web.servlet.DispatcherServlet</servlet-class>
<init-param>
<param-name>contextConfigLocation</param-name>
<param-value>classpath:spring-mvc.xml</param-value>
</init-param>
<load-on-startup>1</load-on-startup>
</servlet>
<servlet-mapping>
<servlet-name>spring</servlet-name>
<url-pattern>/*</url-pattern>
</servlet-mapping>
<listener>
<listener-class>org.springframework.web.context.ContextLoaderListener</listener-class>
</listener>
</web-app>
web.xml文件 是tomcat来解析处理的,解析完成后,调用监听器ContextLoaderListener的初始化方法,进行 spring容器的初始化,
问题1:如何启动springMVC容器?
springMVC的配置文件是在<servlet>标签中指定的,因此需要先加载创建Servlet对象,即DispatcherServlet,才能创建SpringMVC容器;
在解析web.xml中的 <servlet>时,Servlet的生命周期中 初始化方法是init();
即是 DispatcherServlet的init方法,init()在 父类HttpServletBean中实现。然后走FrameworkServlet#initWebApplicationContext()方法,此处即初始化 springMVC容器
class FrameworkServlet{
protected void
configureAndRefreshWebApplicationContext(ConfigurableWebApplicationContext wac){
//添加监听器
wac.addApplicationListener(new SourceFilteringListener(wac, new
FrameworkServlet.ContextRefreshListener()));
this.postProcessWebApplicationContext(wac);
this.applyInitializers(wac);
wac.refresh();
}
}
观察者模式:
AbstractApplicationContext#finishRefresh(){
//事件发布
this.publishEvent((ApplicationEvent)(new ContextRefreshedEvent(this)));->{
DispatcherServlet#onRefresh(ApplicationContext context)->{
initStrategies()-》{
//初始化九大组件
this.initMultipartResolver(context);
this.initLocaleResolver(context);
this.initThemeResolver(context);
this.initHandlerMappings(context);
this.initHandlerAdapters(context);
this.initHandlerExceptionResolvers(context);
this.initRequestToViewNameTranslator(context);
this.initViewResolvers(context);
this.initFlashMapManager(context);
}
}
}
}
}
MVC 9大内置对象/组件:
MultipartResolver request文件上传解析器
LocaleResolver request国际化解析器
ThemeResolver request主题解析器
HandlerMappings request处理器映射表
HandlerAdapters request处理器的适配器
HandlerExceptionResolvers request处理器的异常解析器
RequestToViewNameTranslator request到视图名称的转换器
ViewResolvers 视图解析器
FlashMapManager request发送信号管理器(重定向传递参数)
AbstractApplicationContext#refresh(){
//...
finishRefresh();->{
publishEvent(new ContextRefreshedEvent(this));->{
getApplicationEventMulticaster().multicastEvent(applicationEvent, eventType);->{
invokeListener(listener, event);->{
doInvokeListener(listener, event);->{
listener.onApplicationEvent(event);->{
SourceFilteringListener#onApplicationEvent()->{
onApplicationEventInternal(event);->{
this.delegate.onApplicationEvent(event);->{
GenericApplicationListenerAdapter#onApplicationEvent()->{
FrameworkServlet.ContextRefreshListener#onApplicationEvent()->{
FrameworkServlet.this.onApplicationEvent(event);->{
this.onRefresh(event.getApplicationContext());->{
//到达MVC的Servlet
DispatcherServlet#onRefresh()->{
//初始化组件
//如果有默认值,会直接从DispatcherServlet.properties文件中获取类路径
this.initStrategies(context);
}
}
}
}
}
}
}
}
}
}
}
}
}
}
}
ServletContext 与 ServletConfig的区别:
ServletContext 是指 web.xml文件的所有配置;
ServletConfig是指 <servlet>标签中的配置参数;
Spring中的观察者模式:
广播器/多播器(调用方法 发布 事件,循环监听器 进行事件处理)
事件
监听器(判断事件,处理事件)
二:
SpringMVC容器启动好后,接下来,分析,Servlet的接受请求的 过程:
入口:
diGet();
doPost();
doService();
abstract class FrameworkServlet {
protected abstract void doService(HttpServletRequest var1, HttpServletResponse var2) throws Exception;
protected final void doGet(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException {
this.processRequest(request, response);
}
protected final void doPost(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException {
this.processRequest(request, response);
}
}
请求处理流程:
==
处理请求;处理相应结果;视图渲染
功能流程:
1-上传
2-请求地址映射处理器
请求:Controller的三种实现:
①@Controller;
②实现Controller接口;(同时需要在配置文件中定义name为"/urlName","/"表示请求的映射路径)
③实现HttpRequestHandler接口;(同时需要在配置文件中定义name为"/urlName","/"表示请求的映射路径)
处理器的有映射:
HandlerMapping=BeanNameUrlHandlerMapping,\DefaultAnnotationHandlerMapping
RequestMappingHandlerMapping;Router
BeanNameUrlHandlerMapping 处理 匹配请求的URL并处理。(场景:Controller接口子类,HttpRequestHandler子类)(通过)
RequestMappingHandlerMapping 处理 匹配请求的URL并处理。(场景:注解@Controller)
ApplicationContextAwareProcessor中,初始化了RequestMappingHandlerMapping中的值;
AfterPropertiesSet中,初始化RequestMappingHandlerMapping中的值;
适配器模式,原因,Handler处理器有三种处理方式,因此要使用适配器来适配
参数绑定解析器;
桥接方法;(jdk生成的,不是自己定义的)
@ResponseBody
RequestResponseBodyMethodProcessor;