springmvc源码学习(一)RequestMappingHandlerMapping
2023年6月25日发(作者:)
springmvc源码学习(⼀)RequestMappingHandlerMapping⽬录前⾔RequestMappingHandlerMapping⽤于解析@Controller或@RequestMapping以及@RestController、@GetMapping、@PostMapping,将请求路径与请求⽅法的映射信息放⼊springmvc的容器中。⼀、实例化(1)WebMvcAutoConfigurationWebMvcAutoConfiguration 中标注了@Bean RequestMappingHandlerMapping ,并且⽤了@Primary注解,在RequestMappingHandlerMapping 实例化过程中或执⾏该Bean@Configuration(proxyBeanMethods = false)@ConditionalOnWebApplication(type = T)@ConditionalOnClass({ , , })@ConditionalOnMissingBean()@AutoConfigureOrder(T_PRECEDENCE + 10)@AutoConfigureAfter({ , , })public class WebMvcAutoConfiguration { @Bean @Primary @Override public RequestMappingHandlerMapping requestMappingHandlerMapping( @Qualifier("mvcContentNegotiationManager") ContentNegotiationManager contentNegotiationManager, @Qualifier("mvcConversionService") FormattingConversionService conversionService, @Qualifier("mvcResourceUrlProvider") ResourceUrlProvider resourceUrlProvider) { // Must be @Primary for MvcUriComponentsBuilder to work return tMappingHandlerMapping(contentNegotiationManager, conversionService, resourceUrlProvider); }}(3) //这⾥也标注了@Bean注解 @Bean @SuppressWarnings("deprecation") public RequestMappingHandlerMapping requestMappingHandlerMapping( @Qualifier("mvcContentNegotiationManager") ContentNegotiationManager contentNegotiationManager, @Qualifier("mvcConversionService") FormattingConversionService conversionService, @Qualifier("mvcResourceUrlProvider") ResourceUrlProvider resourceUrlProvider) {
//创建RequestMappingHandlerMapping
RequestMappingHandlerMapping mapping = createRequestMappingHandlerMapping(); //初始化⼀些属性 er(0); erceptors(getInterceptors(conversionService, resourceUrlProvider)); tentNegotiationManager(contentNegotiationManager); sConfigurations(getCorsConfigurations()); PathMatchConfigurer pathConfig = getPathMatchConfigurer(); if (ternParser() != null) { ternParser(ternParser()); } else { PathHelper(PathHelperOrDefault()); hMatcher(hMatcherOrDefault()); Boolean useSuffixPatternMatch = uffixPatternMatch(); if (useSuffixPatternMatch != null) { SuffixPatternMatch(useSuffixPatternMatch); } Boolean useRegisteredSuffixPatternMatch = egisteredSuffixPatternMatch(); if (useRegisteredSuffixPatternMatch != null) { RegisteredSuffixPatternMatch(useRegisteredSuffixPatternMatch); } } Boolean useTrailingSlashMatch = railingSlashMatch(); if (useTrailingSlashMatch != null) { TrailingSlashMatch(useTrailingSlashMatch); } if (hPrefixes() != null) { hPrefixes(hPrefixes()); } return mapping; }(4)createRequestMappingHandlerMapping( )@Override protected RequestMappingHandlerMapping createRequestMappingHandlerMapping() { if (istrations != null) { RequestMappingHandlerMapping mapping = uestMappingHandlerMapping(); if (mapping != null) { return mapping; } } //调⽤⽗类⽅法 return RequestMappingHandlerMapping(); }otected RequestMappingHandlerMapping createRequestMappingHandlerMapping() { //直接new了⼀个 return new RequestMappingHandlerMapping(); }⼆、初始化RequestMappingHandlerMapping实现了InitializingBean接⼝,在初始化过程中会调⽤afterPropertiesSet⽅法(1)afterPropertiesSet( )blic void afterPropertiesSet() { //初始化所有RequestMappingInfo公⽤的⼀些属性rConfiguration = new rConfiguration(); ilingSlashMatch(useTrailingSlashMatch()); tentNegotiationManager(getContentNegotiationManager()); if (getPatternParser() != null) { ternParser(getPatternParser()); (!fixPatternMatch && !isteredSuffixPatternMatch, "Suffix pattern matching not supported with PathPatternParser."); } else { fixPatternMatch(useSuffixPatternMatch()); isteredSuffixPatternMatch(useRegisteredSuffixPatternMatch()); hMatcher(getPathMatcher()); } ropertiesSet(); }(2)ropertiesSet()blic void afterPropertiesSet() { //初始化处理器⽅法 initHandlerMethods(); }protected void initHandlerMethods() { //遍历beanFactory中注册的BeanNames for (String beanName : getCandidateBeanNames()) { if (!With(SCOPED_TARGET_NAME_PREFIX)) { //处理bean processCandidateBean(beanName); } } handlerMethodsInitialized(getHandlerMethods()); }(3)processCandidateBean( )protected void processCandidateBean(String beanName) { Class> beanType = null; try { beanType = obtainApplicationContext().getType(beanName); } catch (Throwable ex) { // An unresolvable bean type, probably from a lazy bean - let's ignore it. if (eEnabled()) { ("Could not resolve type for bean '" + beanName + "'", ex); } } //校验是否是handler if (beanType != null && isHandler(beanType)) { //获取处理器的⽅法 detectHandlerMethods(beanName); }isHandler( )校验是否含有@Controller或@RequestMappingprotected boolean isHandler(Class> beanType) { return (otation(beanType, ) || otation(beanType, )); }(4)detectHandlerMethods( )protected void detectHandlerMethods(Object handler) { Class> handlerType = (handler instanceof String ? obtainApplicationContext().getType((String) handler) : ss()); if (handlerType != null) { //类可能被代理,获取⽤户⾃定义的类 Class> userType = rClass(handlerType); Map methods = Methods(userType, (taLookup) method -> { try { return getMappingForMethod(method, userType); } catch (Throwable ex) { throw new IllegalStateException("Invalid mapping on handler class [" + e() + "]: " + method, ex); } }); if (eEnabled()) { (formatMappings(userType, methods)); } else if (gEnabled()) { (formatMappings(userType, methods)); } h((method, mapping) -> { Method invocableMethod = InvocableMethod(method, userType); //注册处理器⽅法 registerHandlerMethod(handler, invocableMethod, mapping); }); } }(5)selectMethods( )public static Map selectMethods(Class> targetType, final MetadataLookup metadataLookup) { final Map methodMap = new LinkedHashMap<>(); Set> handlerTypes = new LinkedHashSet<>(); Class> specificHandlerType = null; if (!yClass(targetType)) { specificHandlerType = rClass(targetType); (specificHandlerType); } (InterfacesForClassAsSet(targetType)); for (Class> currentHandlerType : handlerTypes) { final Class> targetClass = (specificHandlerType != null ? specificHandlerType : currentHandlerType); //处理所有⽅法以及⽗类的⽅法 Methods(currentHandlerType, method -> { Method specificMethod = tSpecificMethod(method, targetClass); T result = t(specificMethod); if (result != null) { Method bridgedMethod = idgedMethod(specificMethod); if (bridgedMethod == specificMethod || t(bridgedMethod) == null) { //保存⽅法和RequestMappingInfo (specificMethod, result); } } }, _DECLARED_METHODS); } return methodMap; }(6)getMappingForMethod( )protected RequestMappingInfo getMappingForMethod(Method method, Class> handlerType) { //处理⽅法上的@RequestMapping RequestMappingInfo info = createRequestMappingInfo(method); if (info != null) { //处理类上的@RequestMapping RequestMappingInfo typeInfo = createRequestMappingInfo(handlerType); if (typeInfo != null) { //合并操作 info = e(info); } String prefix = getPathPrefix(handlerType); if (prefix != null) { info = (prefix).options().build().combine(info); } } return info; }createRequestMappingInfo( )private RequestMappingInfo createRequestMappingInfo(AnnotatedElement element) { //找@RequestMapping
RequestMapping requestMapping = rgedAnnotation(element, ); RequestCondition> condition = (element instanceof Class ? getCustomTypeCondition((Class>) element) : getCustomMethodCondition((Method) element)); //创建RequestMappingInfo return (requestMapping != null ? createRequestMappingInfo(requestMapping, condition) : null); }createRequestMappingInfo( )protected RequestMappingInfo createRequestMappingInfo( RequestMapping requestMapping, @Nullable RequestCondition> customCondition) { //解析注解RequestMapping中的各种信息 r builder = RequestMappingInfo .paths(resolveEmbeddedValuesInPatterns(())) .methods(()) .params(()) .headers(s()) .consumes(es()) .produces(es()) .mappingName(()); if (customCondition != null) { Condition(customCondition); } return s().build(); }(7)registerHandlerMethod( )注册Controller、method、RequestMappingInfoprotected void registerHandlerMethod(Object handler, Method method, RequestMappingInfo mapping) { erHandlerMethod(handler, method, mapping); updateConsumesCondition(mapping, method); }erHandlerMethod( )protected void registerHandlerMethod(Object handler, Method method, T mapping) { er(mapping, handler, method); }register( )public void register(T mapping, Object handler, Method method) { ock().lock(); try { //创建HandlerMethod HandlerMethod handlerMethod = createHandlerMethod(handler, method); validateMethodMapping(handlerMethod, mapping); Set directPaths = ectPaths(mapping); for (String path : directPaths) { //缓存path和mapping (path, mapping); } String name = null; if (getNamingStrategy() != null) { name = getNamingStrategy().getName(handlerMethod, mapping); //缓存name和handlerMethod addMappingName(name, handlerMethod); } CorsConfiguration corsConfig = initCorsConfiguration(handler, method, mapping); if (corsConfig != null) { teAllowCredentials(); //缓存handlerMethod和corsConfig (handlerMethod, corsConfig); } //缓存mapping和MappingRegistration (mapping, new MappingRegistration<>(mapping, handlerMethod, directPaths, name, corsConfig != null)); } finally { ock().unlock(); } }HandlerMethod的构造⽅法public HandlerMethod(String beanName, BeanFactory beanFactory, Method method) { t(beanName, "Bean name is required"); l(beanFactory, "BeanFactory is required"); l(method, "Method is required"); //bean名称 = beanName; //beanFactory
ctory = beanFactory; Class> beanType = e(beanName); if (beanType == null) { throw new IllegalStateException("Cannot resolve bean type for bean with name '" + beanName + "'"); } //bean类型 pe = rClass(beanType); //⽅法 = method; dMethod = idgedMethod(method); ters = initMethodParameters(); //解析@ResponseStatus evaluateResponseStatus(); ption = initDescription(pe, ); }MappingRegistry 中的⼀些主要属性class MappingRegistry { //RequestMappingInfo与MappingRegistration private final Map> registry = new HashMap<>(); //path和RequestMappingInfo private final MultiValueMap pathLookup = new LinkedMultiValueMap<>(); //name和List private final Map> nameLookup = new ConcurrentHashMap<>(); //HandlerMethod和CorsConfiguration private final Map corsLookup = new ConcurrentHashMap<>(); //读写锁 private final ReentrantReadWriteLock readWriteLock = new ReentrantReadWriteLock(); }(8)updateConsumesCondition(mapping, method)回到第七步中private void updateConsumesCondition(RequestMappingInfo info, Method method) { ConsumesRequestCondition condition = sumesCondition(); if (!y()) { for (Parameter parameter : ameters()) { //@RequestBody MergedAnnotation annot = (parameter).get(); if (ent()) { yRequired(lean("required")); break; } } } }三、getHandler( )(1) dler( ) @Nullable protected HandlerExecutionChain getHandler(HttpServletRequest request) throws Exception { if (rMappings != null) { for (HandlerMapping mapping : rMappings) { //遍历所有handlerMappings,这⾥分析RequestMappingHandlerMapping HandlerExecutionChain handler = dler(request); if (handler != null) { return handler; } } } return null; }(2)dler( )public final HandlerExecutionChain getHandler(HttpServletRequest request) throws Exception { //调⽤⼦类的getHandlerInternal Object handler = getHandlerInternal(request); if (handler == null) { //没有找到,使⽤默认的 handler = getDefaultHandler(); } if (handler == null) { return null; } // Bean name or resolved handler? if (handler instanceof String) { String handlerName = (String) handler; //根据beanName获取Bean handler = obtainApplicationContext().getBean(handlerName); } // Ensure presence of cached lookupPath for interceptors and others if (!hedPath(request)) { initLookupPath(request); } //获取执⾏器链,包含handler和interceptors HandlerExecutionChain executionChain = getHandlerExecutionChain(handler, request); if (eEnabled()) { ("Mapped to " + handler); } else if (gEnabled() && !(patcherType())) { ("Mapped to " + dler()); } //处理跨域 if (hasCorsConfigurationSource(handler) || lightRequest(request)) { CorsConfiguration config = getCorsConfiguration(handler, request); if (getCorsConfigurationSource() != null) { CorsConfiguration globalConfig = getCorsConfigurationSource().getCorsConfiguration(request); config = (globalConfig != null ? e(config) : config); } if (config != null) { teAllowCredentials(); } executionChain = getCorsHandlerExecutionChain(request, executionChain, config); } return executionChain; }(3)dlerInternal( )protected HandlerMethod getHandlerInternal(HttpServletRequest request) throws Exception { Attribute(PRODUCIBLE_MEDIA_TYPES_ATTRIBUTE); try { //⼜进⼊⽗类的getHandlerInternal return dlerInternal(request); } finally { ediaTypesAttribute(request); } }(4)dlerInternal( )protected HandlerMethod getHandlerInternal(HttpServletRequest request) throws Exception { //查找访问的路径,具有全路径匹配、进⾏URL的decode操作、移除URL中分号的内容等功能 String lookupPath = initLookupPath(request); eReadLock(); try { //根据路径找到访问的⽅法,从缓存中获取 HandlerMethod handlerMethod = lookupHandlerMethod(lookupPath, request); //根据Bean name创建Controller Bean对象 return (handlerMethod != null ? WithResolvedBean() : null); } finally { eReadLock(); } }(5)lookupHandlerMethod( )从springmvc容器中找出对应的controller和method的信息,当结果⼤于⼀个时,通过⽐较器⽐较RequestMappingInfo中的各属性,获取最优匹配的⽅法。protected HandlerMethod lookupHandlerMethod(String lookupPath, HttpServletRequest request) throws Exception { List matches = new ArrayList<>(); //从缓存中获取 List directPathMatches = pingsByDirectPath(lookupPath); if (directPathMatches != null) { addMatchingMappings(directPathMatches, matches, request); } if (y()) { addMatchingMappings(istrations().keySet(), matches, request); } if (!y()) { Match bestMatch = (0); //找出最优的匹配⽅法 if (() > 1) { Comparator comparator = new MatchComparator(getMappingComparator(request)); (comparator); bestMatch = (0); if (eEnabled()) { (() + " matching mappings: " + matches); } if (lightRequest(request)) { for (Match match : matches) { if (sConfig()) { return PREFLIGHT_AMBIGUOUS_MATCH; } } } else { Match secondBestMatch = (1); if (e(bestMatch, secondBestMatch) == 0) { Method m1 = dlerMethod().getMethod(); Method m2 = dlerMethod().getMethod(); String uri = uestURI(); throw new IllegalStateException( "Ambiguous handler methods mapped for '" + uri + "': {" + m1 + ", " + m2 + "}"); } } } ribute(BEST_MATCHING_HANDLER_ATTRIBUTE, dlerMethod()); handleMatch(g, lookupPath, request); return dlerMethod(); } else { return handleNoMatch(istrations().keySet(), lookupPath, request); } }总结本⽂简单介绍了RequestMappingHandlerMapping的初始化流程以及解析@Controller或@RequestMapping的流程以及getHandler的过程。
发布者:admin,转转请注明出处:http://www.yc00.com/web/1687682986a31285.html
评论列表(0条)