Spring 中整個處理請求的主流程是啥?經常進行 spring 開發,大家知道攔截器,過濾器,還有具體的 Controller 處理。大體的順序也能理清楚。但是不看源碼總覺得不踏實。那麼 spring 到底是如何處理的呢?事實上,非常簡單。用不了 5 分鐘,你就達到給別人講解程度。
public class DispatcherServlet extends FrameworkServlet {
private List<HandlerAdapter> handlerAdapters;
private List<HandlerMapping> handlerMappings;
private void initHandlerAdapters(ApplicationContext context) {
this.handlerAdapters = null;
if (this.detectAllHandlerAdapters) {
// 從 context 查
Map<String, HandlerAdapter> matchingBeans =
BeanFactoryUtils.beansOfTypeIncludingAncestors(context, HandlerAdapter.class, true, false);
if (!matchingBeans.isEmpty()) {
this.handlerAdapters = new ArrayList<>(matchingBeans.values());
// We keep HandlerAdapters in sorted order.
AnnotationAwareOrderComparator.sort(this.handlerAdapters);
}
}
else {
try {
// 從 context 配置中找
HandlerAdapter ha = context.getBean(HANDLER_ADAPTER_BEAN_NAME, HandlerAdapter.class);
this.handlerAdapters = Collections.singletonList(ha);
}
catch (NoSuchBeanDefinitionException ex) {
// Ignore, we'll add a default HandlerAdapter later.
}
}
// 默認的
if (this.handlerAdapters == null) {
this.handlerAdapters = getDefaultStrategies(context, HandlerAdapter.class);
}
}
private void initHandlerMappings(ApplicationContext context) {
this.handlerMappings = null;
if (this.detectAllHandlerMappings) {
// 從 context 查
Map<String, HandlerMapping> matchingBeans =
BeanFactoryUtils.beansOfTypeIncludingAncestors(context, HandlerMapping.class, true, false);
if (!matchingBeans.isEmpty()) {
this.handlerMappings = new ArrayList<>(matchingBeans.values());
// We keep HandlerMappings in sorted order.
AnnotationAwareOrderComparator.sort(this.handlerMappings);
}
}
else {
try {
// 從 context 配置中找
HandlerMapping hm = context.getBean(HANDLER_MAPPING_BEAN_NAME, HandlerMapping.class);
this.handlerMappings = Collections.singletonList(hm);
}
catch (NoSuchBeanDefinitionException ex) {
// Ignore, we'll add a default HandlerMapping later.
}
}
// 默認的
if (this.handlerMappings == null) {
this.handlerMappings = getDefaultStrategies(context, HandlerMapping.class);
}
}
@Override
protected void doService(HttpServletRequest request, HttpServletResponse response) throws Exception {
// Make framework objects available to handlers and view objects.
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());
doDispatch(request, response);
}
protected void doDispatch(HttpServletRequest request, HttpServletResponse response) throws Exception {
HttpServletRequest processedRequest = request;
try {
// 從 handlerMappings 找到 processedRequest 對應的 HandlerExecutionChain
HandlerExecutionChain mappedHandler = getHandler(processedRequest);
// 調用 mappedHandler 中每個攔截器的 PreHandler 方法。如果某個攔截器返回 false,請求處理就此完成。
if (!mappedHandler.applyPreHandle(processedRequest, response)) {
return;
}
// 從 handlerAdapters 根據 mappedHandler 找到對應的 HandlerAdapter
HandlerAdapter ha = getHandlerAdapter(mappedHandler.getHandler());
// 調用 HandlerAdapter 的 handler 方法處理請求
mv = ha.handle(processedRequest, response, mappedHandler.getHandler());
// 生成 ModelAndView
applyDefaultViewName(processedRequest, mv);
ModelAndView mv = null;
// 調用 mappedHandler 中每個攔截器的 PostHandler 方法。
mappedHandler.applyPostHandle(processedRequest, response, mv);
} catch (Exception var20) {
} catch (Throwable var21) {
}
// 調用 mappedHandler 中每個攔截器的 triggerAfterCompletion 方法。
processDispatchResult(processedRequest, response, mappedHandler, mv, dispatchException);
}
protected HandlerExecutionChain getHandler(HttpServletRequest request) throws Exception {
if (this.handlerMappings != null) {
for (HandlerMapping mapping : this.handlerMappings) {
HandlerExecutionChain handler = mapping.getHandler(request);
if (handler != null) {
return handler;
}
}
}
return null;
}
protected HandlerAdapter getHandlerAdapter(Object handler) throws ServletException {
if (this.handlerAdapters != null) {
for (HandlerAdapter adapter : this.handlerAdapters) {
if (adapter.supports(handler)) {
return adapter;
}
}
}
throw new ServletException("No adapter for handler [" + handler +
"]: The DispatcherServlet configuration needs to include a HandlerAdapter that supports this handler");
}
private void processDispatchResult(HttpServletRequest request, HttpServletResponse response,
@Nullable HandlerExecutionChain mappedHandler, @Nullable ModelAndView mv,
@Nullable Exception exception) throws Exception {
// 生成 ModelAndView
if (mv != null && !mv.wasCleared()) {
render(mv, request, response);
}
if (mappedHandler != null) {
mappedHandler.triggerAfterCompletion(request, response, null);
}
}
protected void render(ModelAndView mv, HttpServletRequest request, HttpServletResponse response) throws Exception {
View view;
String viewName = mv.getViewName();
if (viewName != null) {
// 優先使用 viewName
view = resolveViewName(viewName, mv.getModelInternal(), locale, request);
}
else {
// 其次 View
view = mv.getView();
}
if (mv.getStatus() != null) {
response.setStatus(mv.getStatus().value());
}
view.render(mv.getModelInternal(), request, response);
}
}
處理器相關
public class HandlerExecutionChain {
private final Object handler;
@Nullable
private HandlerInterceptor[] interceptors;
@Nullable
private List<HandlerInterceptor> interceptorList;
private int interceptorIndex = -1;
// 調用每個攔截器的 PreHandler 方法:
// 1. 如果返回 true,繼續下一個攔截器。
// 2. 如果返回 false,調用已調用 preHandler 方法的攔截器的 afterCompletion,請求處理就此完成。
boolean applyPreHandle(HttpServletRequest request, HttpServletResponse response) throws Exception {
HandlerInterceptor[] interceptors = getInterceptors();
if (!ObjectUtils.isEmpty(interceptors)) {
for (int i = 0; i < interceptors.length; i++) {
HandlerInterceptor interceptor = interceptors[i];
if (!interceptor.preHandle(request, response, this.handler)) {
triggerAfterCompletion(request, response, null);
return false;
}
this.interceptorIndex = i;
}
}
return true;
}
// 調用每個攔截器的 PostHandler 方法。
void applyPostHandle(HttpServletRequest request, HttpServletResponse response, @Nullable ModelAndView mv)
throws Exception {
HandlerInterceptor[] interceptors = getInterceptors();
if (!ObjectUtils.isEmpty(interceptors)) {
for (int i = interceptors.length - 1; i >= 0; i--) {
HandlerInterceptor interceptor = interceptors[i];
interceptor.postHandle(request, response, this.handler, mv);
}
}
}
void triggerAfterCompletion(HttpServletRequest request, HttpServletResponse response, @Nullable Exception ex)
throws Exception {
HandlerInterceptor[] interceptors = getInterceptors();
if (!ObjectUtils.isEmpty(interceptors)) {
for (int i = this.interceptorIndex; i >= 0; i--) {
HandlerInterceptor interceptor = interceptors[i];
try {
interceptor.afterCompletion(request, response, this.handler, ex);
}
catch (Throwable ex2) {
logger.error("HandlerInterceptor.afterCompletion threw exception", ex2);
}
}
}
}
}
總結
整個處理流程
- 初始化 handlerAdapters 和 handlerMappings
- 根據 mappedHandler 從 handlerMappings 找到 mappedHandler
- 調用 mappedHandler 中每個攔截器的 PreHandler 方法。如果某個攔截器返回 false,請求處理就此完成。
- 調用 HandlerAdapter 的 handler 方法處理請求
- 生成 View
- 調用 mappedHandler 中每個攔截器的 PostHandler 方法
- 調用 mappedHandler 中每個攔截器的 triggerAfterCompletion 方法(即使有異常,該方法也確保執行)
所以整個處理流程的核心是 HandlerAdapter 的 handler 方法。關於 HandlerAdapter 的 handler 下篇文章詳述。