調用鏈:ios
AbstractApplicationContext#refresh() --> AbstractApplicationContext#finishBeanFactoryInitialization() --> DefaultListableBeanFactory#preInstantiateSingletons() --> AbstractBeanFactory#getBean() --> AbstractBeanFactory#doGetBean() --> AbstractAutowireCapableBeanFactory#createBean() --> AbstractAutowireCapableBeanFactory#doCreateBean() --> AbstractAutowireCapableBeanFactory#initializeBean() --> AbstractAutowireCapableBeanFactory#invokeInitMethods() --> RequestMappingHandlerMapping#afterPropertiesSet() --> AbstractHandlerMethodMapping#afterPropertiesSet() --> AbstractHandlerMethodMapping#initHandlerMethods() --> AbstractHandlerMethodMapping#processCandidateBean --> AbstractHandlerMethodMapping#detectHandlerMethods() --> RequestMappingHandlerMapping#registerHandlerMethod() --> AbstractHandlerMethodMapping#registerHandlerMethod()app
在AbstractHandlerMethodMapping#initHandlerMethods()中先獲取全部的beanName,再挑選出符合條件的進行處理cors
protected void initHandlerMethods() { //獲取容器中全部beanName for (String beanName : getCandidateBeanNames()) { if (!beanName.startsWith(SCOPED_TARGET_NAME_PREFIX)) { processCandidateBean(beanName); } } handlerMethodsInitialized(getHandlerMethods()); }
判斷是Handler的才繼續調用detectHandlerMethods方法async
protected void processCandidateBean(String beanName) { Class<?> beanType = null; ...... if (beanType != null && isHandler(beanType)) { detectHandlerMethods(beanName); } }
知足handler的條件是(RequestMappingHandlerMapping#isHandler()):@Controller或@RequestMapping進行註解ide
@Override protected boolean isHandler(Class<?> beanType) { return (AnnotatedElementUtils.hasAnnotation(beanType, Controller.class) || AnnotatedElementUtils.hasAnnotation(beanType, RequestMapping.class)); }
知足條件的,進行註冊
RequestMappingHandlerMapping#registerHandlerMethod()post
@Override protected void registerHandlerMethod(Object handler, Method method, RequestMappingInfo mapping) { super.registerHandlerMethod(handler, method, mapping); updateConsumesCondition(mapping, method); }
AbstractHandlerMethodMapping#registerHandlerMethod()this
protected void registerHandlerMethod(Object handler, Method method, T mapping) { this.mappingRegistry.register(mapping, handler, method); }
完成註冊。AbstractHandlerMethodMapping#register()spa
public void register(T mapping, Object handler, Method method) { this.readWriteLock.writeLock().lock(); try { HandlerMethod handlerMethod = createHandlerMethod(handler, method); validateMethodMapping(handlerMethod, mapping); Set<String> directPaths = AbstractHandlerMethodMapping.this.getDirectPaths(mapping); for (String path : directPaths) { this.pathLookup.add(path, mapping); } String name = null; if (getNamingStrategy() != null) { name = getNamingStrategy().getName(handlerMethod, mapping); addMappingName(name, handlerMethod); } CorsConfiguration config = initCorsConfiguration(handler, method, mapping); if (config != null) { config.validateAllowCredentials(); this.corsLookup.put(handlerMethod, config); } this.registry.put(mapping, new MappingRegistration<>(mapping, handlerMethod, directPaths, name)); } finally { this.readWriteLock.writeLock().unlock(); } }
調用鏈:code
Standardwrapper#initServlet() --> HttpServletBean#init() --> FrameworkServlet#initServletBean() --> FrameworkServlet#initWebApplicationContext() --> DispatcherServlet#onRefresh() --> DispatcherServlet#initStrategies() -->
DispatcherServlet#initHandlerMappings()ip
http請求時,先initHandlerMappings.
matchingBeans會存儲獲取到全部符合條件的,再給handlerMappings賦值
private void initHandlerMappings(ApplicationContext context) { this.handlerMappings = null; if (this.detectAllHandlerMappings) { // Find all HandlerMappings in the ApplicationContext, including ancestor contexts. 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); } } }
其中BeanFactoryUtils.beansOfTypeIncludingAncestors(context, HandlerMapping.class, true, false);會先調用AbstractApplicationContext#getBeansOfType(),再調用DefaultListableBeanFactory#getBeansOfType()
先獲取beanName requestMappingHandlerMapping,再根據beanName(requestMappingHandlerMapping)從容器獲取beanInstance。最後put到result中返回
@Override @SuppressWarnings("unchecked") public <T> Map<String, T> getBeansOfType( @Nullable Class<T> type, boolean includeNonSingletons, boolean allowEagerInit) throws BeansException { //獲取requestMappingHandlerMapping String[] beanNames = getBeanNamesForType(type, includeNonSingletons, allowEagerInit); Map<String, T> result = CollectionUtils.newLinkedHashMap(beanNames.length); for (String beanName : beanNames) { try { ////再根據beanName(requestMappingHandlerMapping)從容器獲取beanInstance Object beanInstance = getBean(beanName); if (!(beanInstance instanceof NullBean)) { result.put(beanName, (T) beanInstance); } } ...... return result; }
從而在initHandlerMappings給handlerMappings賦值完成
this.handlerMappings = new ArrayList<>(matchingBeans.values());
獲取當前請求的handler和HandlerAdapter
DispatcherServlet#doDispatch()
mappedHandler = getHandler(processedRequest);
DispatcherServlet#getHandler()
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; }
經過反射方式請求controller中方法:
// Actually invoke the handler. mv = ha.handle(processedRequest, response, mappedHandler.getHandler());
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); // Determine handler for the current request. mappedHandler = getHandler(processedRequest); if (mappedHandler == null) { noHandlerFound(processedRequest, response); return; } // Determine handler adapter for the current request. HandlerAdapter ha = getHandlerAdapter(mappedHandler.getHandler()); // Process last-modified header, if supported by the handler. 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; } // Actually invoke the handler. 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) { // As of 4.3, we're processing Errors thrown from handler methods as well, // making them available for @ExceptionHandler methods and other scenarios. 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()) { // Instead of postHandle and afterCompletion if (mappedHandler != null) { mappedHandler.applyAfterConcurrentHandlingStarted(processedRequest, response); } } else { // Clean up any resources used by a multipart request. if (multipartRequestParsed) { cleanupMultipart(processedRequest); } } } }