HttpServletBean
建立springmvc框架 与servlet API的联系。
init()
public final void init()
throws ServletException {
if (logger.isDebugEnabled()) {
logger.debug(
"Initializing servlet '" + getServletName() +
"'");
}
try {
PropertyValues pvs =
new ServletConfigPropertyValues(getServletConfig(),
this.requiredProperties);
BeanWrapper bw = PropertyAccessorFactory.forBeanPropertyAccess(
this);
ResourceLoader resourceLoader =
new ServletContextResourceLoader(getServletContext());
bw.registerCustomEditor(Resource.class,
new ResourceEditor(resourceLoader, getEnvironment()));
initBeanWrapper(bw);
bw.setPropertyValues(pvs,
true);
}
catch (BeansException ex) {
if (logger.isErrorEnabled()) {
logger.error(
"Failed to set bean properties on servlet '" + getServletName() +
"'", ex);
}
throw ex;
}
initServletBean();
if (logger.isDebugEnabled()) {
logger.debug(
"Servlet '" + getServletName() +
"' configured successfully");
}
}
FrameworkServlet
initServletBean : 子类自定义初始化
protected final void initServletBean()
throws ServletException {
getServletContext().log(
"Initializing Spring FrameworkServlet '" + getServletName() +
"'");
if (
this.logger.isInfoEnabled()) {
this.logger.info(
"FrameworkServlet '" + getServletName() +
"': initialization started");
}
long startTime = System.currentTimeMillis();
try {
this.webApplicationContext = initWebApplicationContext();
initFrameworkServlet();
}
catch (ServletException ex) {
this.logger.error(
"Context initialization failed", ex);
throw ex;
}
catch (RuntimeException ex) {
this.logger.error(
"Context initialization failed", ex);
throw ex;
}
if (
this.logger.isInfoEnabled()) {
long elapsedTime = System.currentTimeMillis() - startTime;
this.logger.info(
"FrameworkServlet '" + getServletName() +
"': initialization completed in " +
elapsedTime +
" ms");
}
}
springmvc 启动时-》web.xml配置中声明的ContextLoaderListener、DispatcherServlet完成所有任务。
1.ContextLoaderListener(环境加载)
完成对spring配置文件的加载。
2.DispatcherServlet(中央调节作用)
spring中央控制器,拦截request请求,由handlerMapping -》handler-》DispatcherServlet-》handlerAdapter-》modelAndView》DispatcherServlet-》viewResolver-》response。
ContextLoaderListener
加载spring配置文件
ContextLoaderListener实现了ServletContextListener,在容器启动时会调用contextInitialized
public void contextInitialized(ServletContextEvent event) {
initWebApplicationContext(event.getServletContext());
}
继续跟踪如何初始化WebApplicationContext
public WebApplicationContext
initWebApplicationContext(ServletContext servletContext) {
if (servletContext.getAttribute(WebApplicationContext.ROOT_WEB_APPLICATION_CONTEXT_ATTRIBUTE) !=
null) {
throw new IllegalStateException(
"Cannot initialize context because there is already a root application context present - " +
"check whether you have multiple ContextLoader* definitions in your web.xml!");
}
long startTime = System.currentTimeMillis();
try {
if (
this.context ==
null) {
this.context = createWebApplicationContext(servletContext);
}
if (
this.context
instanceof ConfigurableWebApplicationContext) {
ConfigurableWebApplicationContext cwac = (ConfigurableWebApplicationContext)
this.context;
if (!cwac.isActive()) {
if (cwac.getParent() ==
null) {
ApplicationContext parent = loadParentContext(servletContext);
cwac.setParent(parent);
}
configureAndRefreshWebApplicationContext(cwac, servletContext);
}
}
servletContext.setAttribute(WebApplicationContext.ROOT_WEB_APPLICATION_CONTEXT_ATTRIBUTE,
this.context);
ClassLoader ccl = Thread.currentThread().getContextClassLoader();
if (ccl == ContextLoader.class.getClassLoader()) {
currentContext =
this.context;
}
else if (ccl !=
null) {
currentContextPerThread.put(ccl,
this.context);
}
return this.context;
}
catch (RuntimeException ex) {
servletContext.setAttribute(WebApplicationContext.ROOT_WEB_APPLICATION_CONTEXT_ATTRIBUTE, ex);
throw ex;
}
catch (Error err) {
servletContext.setAttribute(WebApplicationContext.ROOT_WEB_APPLICATION_CONTEXT_ATTRIBUTE, err);
throw err;
}
}
DispatcherServlet
DispatcherServlet也是Servlet的实现类,对于http各种request(请求)方式会进行拦截,进行统一处理后,解析拦截的请求为handlerMapping(处理器映射器),由handlerMapping映射到handlerAdapter(处理器适配器),由相应的handlerAdapter返回modelAndView对象返回,进行viewResolver(视图解析器渲染)后,response(响应)给client。
protected void doDispatch(HttpServletRequest request, HttpServletResponse response)
throws Exception {
HttpServletRequest processedRequest = request;
HandlerExecutionChain mappedHandler =
null;
boolean multipartRequestParsed =
false;
WebAsyncManager asyncManager = WebAsyncUtils.getAsyncManager(request);
try {
ModelAndView mv =
null;
Exception dispatchException =
null;
try {
processedRequest = checkMultipart(request);
multipartRequestParsed = (processedRequest != request);
mappedHandler = getHandler(processedRequest);
if (mappedHandler ==
null || mappedHandler.getHandler() ==
null) {
noHandlerFound(processedRequest, response);
return;
}
HandlerAdapter ha = getHandlerAdapter(mappedHandler.getHandler());
String method = request.getMethod();
boolean isGet =
"GET".equals(method);
if (isGet ||
"HEAD".equals(method)) {
long lastModified = ha.getLastModified(request, mappedHandler.getHandler());
if (logger.isDebugEnabled()) {
logger.debug(
"Last-Modified value for [" + getRequestUri(request) +
"] is: " + lastModified);
}
if (
new ServletWebRequest(request, response).checkNotModified(lastModified) && isGet) {
return;
}
}
if (!mappedHandler.applyPreHandle(processedRequest, response)) {
return;
}
mv = ha.handle(processedRequest, response, mappedHandler.getHandler());
if (asyncManager.isConcurrentHandlingStarted()) {
return;
}
applyDefaultViewName(processedRequest, mv);
mappedHandler.applyPostHandle(processedRequest, response, mv);
}
catch (Exception ex) {
dispatchException = ex;
}
catch (Throwable err) {
dispatchException =
new NestedServletException(
"Handler dispatch failed", err);
}
processDispatchResult(processedRequest, response, mappedHandler, mv, dispatchException);
}
catch (Exception ex) {
triggerAfterCompletion(processedRequest, response, mappedHandler, ex);
}
catch (Throwable err) {
triggerAfterCompletion(processedRequest, response, mappedHandler,
new NestedServletException(
"Handler processing failed", err));
}
finally {
if (asyncManager.isConcurrentHandlingStarted()) {
if (mappedHandler !=
null) {
mappedHandler.applyAfterConcurrentHandlingStarted(processedRequest, response);
}
}
else {
if (multipartRequestParsed) {
cleanupMultipart(processedRequest);
}
}
}
}
protected void initStrategies(ApplicationContext context) {
initMultipartResolver(context);
initLocaleResolver(context);
initThemeResolver(context);
initHandlerMappings(context);
initHandlerAdapters(context);
initHandlerExceptionResolvers(context);
initRequestToViewNameTranslator(context);
initViewResolvers(context);
initFlashMapManager(context);
}
initMultipartResolver、initLocaleResolver、initThemeResolver相同的原理,只需配置对应的实现类,并保持默认名即可。
上述三者不存在时,则默认为null处理,initRequestToViewNameTranslator、initFlashMapManager不同之处为,不存在时,将会以spring默认的策略生成。
private void initMultipartResolver(ApplicationContext context) {
try {
this.multipartResolver = context.getBean(MULTIPART_RESOLVER_BEAN_NAME, MultipartResolver.class);
}
catch (NoSuchBeanDefinitionException ex) {
this.multipartResolver =
null;
}
}
initHandlerMappings、initHandlerAdapters、initHandlerExceptionResolvers、initViewResolvers相同原理,由DispatcherServlet对应属性生成配置方式。
1.查询所有的映射器/适配器/...
2.只加载配置特定name的映射器/适配器/...
3.加载默认的映射器/适配器/...
private void initHandlerMappings(ApplicationContext context) {
this.handlerMappings =
null;
if (
this.detectAllHandlerMappings) {
Map<String, HandlerMapping> matchingBeans =
BeanFactoryUtils.beansOfTypeIncludingAncestors(context, HandlerMapping.class,
true,
false);
if (!matchingBeans.isEmpty()) {
this.handlerMappings =
new ArrayList<>(matchingBeans.values());
AnnotationAwareOrderComparator.sort(
this.handlerMappings);
}
}
else {
try {
HandlerMapping hm = context.getBean(HANDLER_MAPPING_BEAN_NAME, HandlerMapping.class);
this.handlerMappings = Collections.singletonList(hm);
}
catch (NoSuchBeanDefinitionException ex) {
}
}
if (
this.handlerMappings ==
null) {
this.handlerMappings = getDefaultStrategies(context, HandlerMapping.class);
}
}
完成配置的初始化,对请求的doDispatch 完成逻辑处理。
protected void doDispatch(HttpServletRequest request, HttpServletResponse response)
throws Exception {
HttpServletRequest processedRequest = request;
HandlerExecutionChain mappedHandler =
null;
boolean multipartRequestParsed =
false;
WebAsyncManager asyncManager = WebAsyncUtils.getAsyncManager(request);
try {
ModelAndView mv =
null;
Exception dispatchException =
null;
try {
processedRequest = checkMultipart(request);
multipartRequestParsed = (processedRequest != request);
mappedHandler = getHandler(processedRequest);
if (mappedHandler ==
null || mappedHandler.getHandler() ==
null) {
noHandlerFound(processedRequest, response);
return;
}
HandlerAdapter ha = getHandlerAdapter(mappedHandler.getHandler());
String method = request.getMethod();
boolean isGet =
"GET".equals(method);
if (isGet ||
"HEAD".equals(method)) {
long lastModified = ha.getLastModified(request, mappedHandler.getHandler());
if (
new ServletWebRequest(request, response).checkNotModified(lastModified) && isGet) {
return;
}
}
if (!mappedHandler.applyPreHandle(processedRequest, response)) {
return;
}
mv = ha.handle(processedRequest, response, mappedHandler.getHandler());
if (asyncManager.isConcurrentHandlingStarted()) {
return;
}
applyDefaultViewName(processedRequest, mv);
mappedHandler.applyPostHandle(processedRequest, response, mv);
}