能夠看到有幾個生命週期接口:java
ApplicationContextAware:保存了spring上下文web
public interface ApplicationContextAware extends Aware {
//上下文初始化完成後被調用
void setApplicationContext(ApplicationContext applicationContext) throws BeansException;
}
#org.springframework.web.servlet.FrameworkServlet
//保存SpringMVC上下文 當經過Spring裝載DispatchServlet時會被調用
@Override
public void setApplicationContext(ApplicationContext applicationContext) {
if (this.webApplicationContext == null && applicationContext instanceof WebApplicationContext) {
this.webApplicationContext = (WebApplicationContext) applicationContext;
this.webApplicationContextInjected = true;
}
}
複製代碼
EnvironmentAware:保存了環境變量對象spring
public interface EnvironmentAware extends Aware {
//環境變量對象初始化完成後被調用
void setEnvironment(Environment environment);
}
#org.springframework.web.servlet.HttpServletBean
@Override
public void setEnvironment(Environment environment) {
Assert.isInstanceOf(ConfigurableEnvironment.class, environment, "ConfigurableEnvironment required");
this.environment = (ConfigurableEnvironment) environment;
}
複製代碼
Servlet:Servlet生命週期網絡
public interface Servlet {
//serlvet初始化
public void init(ServletConfig config) throws ServletException;
public ServletConfig getServletConfig();
public void service(ServletRequest req, ServletResponse res)
throws ServletException, IOException;
public String getServletInfo();
//serlvet銷燬
public void destroy();
}
#org.springframework.web.servlet.HttpServletBean
@Override
public final void init() throws ServletException {
...
initServletBean();
}
@Override
public void destroy() {
if (this.webApplicationContext instanceof ConfigurableApplicationContext && !this.webApplicationContextInjected) {
//銷燬上下文
((ConfigurableApplicationContext) this.webApplicationContext).close();
}
}
#org.springframework.web.servlet.FrameworkServlet
DispatcherServlet extends FrameworkServlet
#org.springframework.web.servlet.FrameworkServlet
@Override
protected final void initServletBean() throws ServletException {
...
try {
this.webApplicationContext = initWebApplicationContext();
initFrameworkServlet();
}
...
}
protected WebApplicationContext initWebApplicationContext() {
WebApplicationContext rootContext =
WebApplicationContextUtils.getWebApplicationContext(getServletContext());
WebApplicationContext wac = null;
...
//以spring配置方式時webApplicationContext!=null
if (this.webApplicationContext != null) {
wac = this.webApplicationContext;
if (wac instanceof ConfigurableWebApplicationContext) {
ConfigurableWebApplicationContext cwac = (ConfigurableWebApplicationContext) wac;
cwac.setParent(rootContext);
}
}
}
if (wac == null) {
//建立applicationContext
wac = createWebApplicationContext(rootContext);
}
...
return wac;
}
protected WebApplicationContext createWebApplicationContext(ApplicationContext parent) {
//XmlWebApplicationContext
Class<?> contextClass = getContextClass();
...
//建立applicationContext
ConfigurableWebApplicationContext wac =
(ConfigurableWebApplicationContext) BeanUtils.instantiateClass(contextClass);
wac.setEnvironment(getEnvironment());
//設置parent(ContextLoadListener中建立的applicationContext)
wac.setParent(parent);
//讀取contextConfigLocation配置
wac.setConfigLocation(getContextConfigLocation());
//refresh()
configureAndRefreshWebApplicationContext(wac);
return wac;
}
//當SpringMVC上下初始化完成後會去裝載默認策略(HandlerMapping,HandleAdapter)
protected void initStrategies(ApplicationContext context) {
//獲取容器中是否有其實現 沒有則加載DispatcherServlet.properties中的默認實現
initMultipartResolver(context);
initLocaleResolver(context);
initThemeResolver(context);
initHandlerMappings(context);
initHandlerAdapters(context);
initHandlerExceptionResolvers(context);
initRequestToViewNameTranslator(context);
initViewResolvers(context);
initFlashMapManager(context);
}
複製代碼
org.springframework.web.servlet.LocaleResolver=org.springframework.web.servlet.i18n.AcceptHeaderLocaleResolver
org.springframework.web.servlet.ThemeResolver=org.springframework.web.servlet.theme.FixedThemeResolver
org.springframework.web.servlet.HandlerMapping=org.springframework.web.servlet.handler.BeanNameUrlHandlerMapping,\
org.springframework.web.servlet.mvc.annotation.DefaultAnnotationHandlerMapping
org.springframework.web.servlet.HandlerAdapter=org.springframework.web.servlet.mvc.HttpRequestHandlerAdapter,\
org.springframework.web.servlet.mvc.SimpleControllerHandlerAdapter,\
org.springframework.web.servlet.mvc.annotation.AnnotationMethodHandlerAdapter
org.springframework.web.servlet.HandlerExceptionResolver=org.springframework.web.servlet.mvc.annotation.AnnotationMethodHandlerExceptionResolver,\
org.springframework.web.servlet.mvc.annotation.ResponseStatusExceptionResolver,\
org.springframework.web.servlet.mvc.support.DefaultHandlerExceptionResolver
org.springframework.web.servlet.RequestToViewNameTranslator=org.springframework.web.servlet.view.DefaultRequestToViewNameTranslator
org.springframework.web.servlet.ViewResolver=org.springframework.web.servlet.view.InternalResourceViewResolver
org.springframework.web.servlet.FlashMapManager=org.springframework.web.servlet.support.SessionFlashMapManager
複製代碼
@Override
protected void doService(HttpServletRequest request, HttpServletResponse response) throws Exception {
//將相關配置設置到request做用於中
request.setAttribute(WEB_APPLICATION_CONTEXT_ATTRIBUTE, getWebApplicationContext());
request.setAttribute(LOCALE_RESOLVER_ATTRIBUTE, this.localeResolver);
request.setAttribute(THEME_RESOLVER_ATTRIBUTE, this.themeResolver);
request.setAttribute(THEME_SOURCE_ATTRIBUTE, getThemeSource());
...
request.setAttribute(OUTPUT_FLASH_MAP_ATTRIBUTE, new FlashMap());
request.setAttribute(FLASH_MAP_MANAGER_ATTRIBUTE, this.flashMapManager);
try {
doDispatch(request, response);
}
}
protected void doDispatch(HttpServletRequest request, HttpServletResponse response) throws Exception {
...
try {
ModelAndView mv = null;
Exception dispatchException = null;
try {
processedRequest = checkMultipart(request);
multipartRequestParsed = (processedRequest != request);
//1.調用handlerMapping獲取handlerChain
mappedHandler = getHandler(processedRequest);
if (mappedHandler == null || mappedHandler.getHandler() == null) {
noHandlerFound(processedRequest, response);
return;
}
// 2.獲取支持該handler解析的HandlerAdapter
HandlerAdapter ha = getHandlerAdapter(mappedHandler.getHandler());
//前置處理(CORS時用到)
if (!mappedHandler.applyPreHandle(processedRequest, response)) {
return;
}
// 3.使用HandlerAdapter完成handler處理
mv = ha.handle(processedRequest, response, mappedHandler.getHandler());
//若是是異步請求 直接返回
if (asyncManager.isConcurrentHandlingStarted()) {
return;
}
applyDefaultViewName(request, mv);
//後置處理
mappedHandler.applyPostHandle(processedRequest, response, mv);
}
catch (Exception ex) {
dispatchException = ex;
}
//4.異常處理,視圖解析,渲染返回
processDispatchResult(processedRequest, response, mappedHandler, mv, dispatchException);
}
...
}
private void processDispatchResult(HttpServletRequest request, HttpServletResponse response, HandlerExecutionChain mappedHandler, ModelAndView mv, Exception exception) throws Exception {
boolean errorView = false;
//若是HandlerAdapter.handler()執行異常 則進行異常處理
if (exception != null) {
...
Object handler = (mappedHandler != null ? mappedHandler.getHandler() : null);
//4.1
mv = processHandlerException(request, response, handler, exception);
errorView = (mv != null);
}
if (mv != null && !mv.wasCleared()) {
//4.2 視圖解析 渲染返回
render(mv, request, response);
if (errorView) {
WebUtils.clearErrorRequestAttributes(request);
}
}
}
//異常處理
protected ModelAndView processHandlerException(HttpServletRequest request, HttpServletResponse response, Object handler, Exception ex) throws Exception {
ModelAndView exMv = null;
for (HandlerExceptionResolver handlerExceptionResolver : this.handlerExceptionResolvers) {
//使用異常解析器解析異常(相似HandlerAdapter參數解析,調用)
exMv = handlerExceptionResolver.resolveException(request, response, handler, ex);
if (exMv != null) {
break;
}
}
...
}
protected void render(ModelAndView mv, HttpServletRequest request, HttpServletResponse response) throws Exception {
//國際化
Locale locale = this.localeResolver.resolveLocale(request);
response.setLocale(locale);
View view;
if (mv.isReference()) {
//4.2.1視圖解析
view = resolveViewName(mv.getViewName(), mv.getModelInternal(), locale, request);
...
}
else {
view = mv.getView();
}
....
try {
if (mv.getStatus() != null) {
response.setStatus(mv.getStatus().value());
}
//渲染返回
view.render(mv.getModelInternal(), request, response);
}
...
}
protected View resolveViewName(String viewName, Map<String, Object> model, Locale locale, HttpServletRequest request) throws Exception {
//視圖解析
for (ViewResolver viewResolver : this.viewResolvers) {
View view = viewResolver.resolveViewName(viewName, locale);
if (view != null) {
return view;
}
}
return null;
}
複製代碼
過程歸納:mvc
上述圖片來自網絡