日韩性视频-久久久蜜桃-www中文字幕-在线中文字幕av-亚洲欧美一区二区三区四区-撸久久-香蕉视频一区-久久无码精品丰满人妻-国产高潮av-激情福利社-日韩av网址大全-国产精品久久999-日本五十路在线-性欧美在线-久久99精品波多结衣一区-男女午夜免费视频-黑人极品ⅴideos精品欧美棵-人人妻人人澡人人爽精品欧美一区-日韩一区在线看-欧美a级在线免费观看

歡迎訪問 生活随笔!

生活随笔

當(dāng)前位置: 首頁 > 编程语言 > c/c++ >内容正文

c/c++

spring MVC RequestMappingHandlerMapping解析

發(fā)布時(shí)間:2024/9/19 c/c++ 37 豆豆
生活随笔 收集整理的這篇文章主要介紹了 spring MVC RequestMappingHandlerMapping解析 小編覺得挺不錯(cuò)的,現(xiàn)在分享給大家,幫大家做個(gè)參考.

spring MVC RequestMappingHandlerMapping解析

getHandler(HttpServletRequest request)

在doDispatch(HttpServletRequest request, HttpServletResponse response)中,調(diào)用過getHandler(HttpServletRequest request)。

DispatcherServlet)的getHandler(HttpServletRequest request方法,該方法遍歷所有HandlerMapping并找到匹配的HandlerExecutionChain并返回HandlerExecutionChain對(duì)象。源碼如下:

@Nullableprotected HandlerExecutionChain getHandler(HttpServletRequest request) throws Exception {if (this.handlerMappings != null) {//遍歷HandlerMappingfor (HandlerMapping mapping : this.handlerMappings) {//找到匹配的HandlerExecutionChainHandlerExecutionChain handler = mapping.getHandler(request);if (handler != null) {return handler;}}}return null;}

HandlerExecutionChain

我們打開HandlerExecutionChain看一下,發(fā)現(xiàn)他是一個(gè)包含Handler(我們平時(shí)叫Handler,后面你會(huì)發(fā)現(xiàn)其實(shí)他是HandlerMethod的子類)和HandlerInterceptor。

根據(jù)源碼的注釋,我們可以得知這個(gè)HandlerExecutionChain是一個(gè)調(diào)用執(zhí)行鏈,包含了HandlerInterceptor和handler。

/*** Handler execution chain, consisting of handler object and any handler interceptors.* Returned by HandlerMapping's {@link HandlerMapping#getHandler} method.** @author Juergen Hoeller* @since 20.06.2003* @see HandlerInterceptor*/ public class HandlerExecutionChain {private static final Log logger = LogFactory.getLog(HandlerExecutionChain.class);//handlerprivate final Object handler;//HandlerInterceptor數(shù)組@Nullableprivate HandlerInterceptor[] interceptors;//HandlerInterceptor的List@Nullableprivate List<HandlerInterceptor> interceptorList;//interceptor的下標(biāo),應(yīng)該是代表執(zhí)行到哪一個(gè)HandlerInterceptorprivate int interceptorIndex = -1;

RequestMappingHandlerMapping

HandlerMapping是一個(gè)接口,HandlerMapping的實(shí)現(xiàn)類是有十分多的,RequestMappingHandlerMapping類做為重點(diǎn)介紹。根據(jù)RequestMappingHandlerMapping的注釋,該類用于創(chuàng)建@RequestMapping和@Controller注解的實(shí)例。


RequestMappingHandlerMapping的初始化

找到RequestMappingHandlerMapping的afterPropertiesSet()方法,這個(gè)方法來自InitializingBean接口,根據(jù)Bean的生命周期可以知道,當(dāng)做完bean屬性填充之后我們會(huì)調(diào)用InitializingBean.afterPropertiesSet()

@Override @SuppressWarnings("deprecation") public void afterPropertiesSet() {//創(chuàng)建RequestMappingInfo.BuilderConfiguration對(duì)象,創(chuàng)建配置信息用this.config = new RequestMappingInfo.BuilderConfiguration();//調(diào)用setter設(shè)置各種屬性this.config.setUrlPathHelper(getUrlPathHelper());this.config.setPathMatcher(getPathMatcher());this.config.setSuffixPatternMatch(useSuffixPatternMatch());this.config.setTrailingSlashMatch(useTrailingSlashMatch());this.config.setRegisteredSuffixPatternMatch(useRegisteredSuffixPatternMatch());this.config.setContentNegotiationManager(getContentNegotiationManager());//調(diào)用父類AbstractHandlerMethodMapping的afterPropertiesSet()super.afterPropertiesSet(); }

找到AbstractHandlerMethodMapping(一個(gè)抽象類)的afterPropertiesSet()。我講一下,這個(gè)afterPropertiesSet()做了什么操作,代碼有點(diǎn)長(zhǎng),但是核心操作就幾個(gè):

  • 調(diào)用getCandidateBeanNames()從上下文中掃描合適的bean,并獲取候選bean的名字(@Controller注解的bean)
  • 調(diào)用processCandidateBean(String beanName)從上下文中獲取對(duì)應(yīng)beanName的beanType,并將beanType傳遞給isHandler(Class<?> beanType)
  • isHandler(Class<?> beanType)判斷是否@RequestMapping和@Controller注解的實(shí)例
  • 經(jīng)過isHandler(Class<?> beanType)過濾的beanName會(huì)并將符合要求的beanName丟給detectHandlerMethods(Object handler) 方法處理。
  • detectHandlerMethods(Object handler)會(huì)找處指定的handler bean中的handler methods(符合的@RequestMapping注解過的方法),并調(diào)用registerHandlerMethod(Object handler, Method method, RequestMappingInfo mapping)去注冊(cè)方法
  • 調(diào)用getHandlerMethods(),獲取從this.mappingRegistry獲取HandlerMethods
  • 最后調(diào)用handlerMethodsInitialized()作一些初始化后的日志工作

因?yàn)檎{(diào)用方法比較多,我分開展示:

initHandlerMethods()

/*** Detects handler methods at initialization.* @see #initHandlerMethods*/@Overridepublic void afterPropertiesSet() {//去調(diào)用下面的initHandlerMethods()initHandlerMethods();}/*** Scan beans in the ApplicationContext, detect and register handler methods.* @see #getCandidateBeanNames()* @see #processCandidateBean* @see #handlerMethodsInitialized*/protected void initHandlerMethods() {//getCandidateBeanNames()從上下文中掃描合適的bean的名字for (String beanName : getCandidateBeanNames()) {//必須不帶“scopedTarget.”前綴的bean名if (!beanName.startsWith(SCOPED_TARGET_NAME_PREFIX)) {//發(fā)現(xiàn)并注冊(cè)handler methodsprocessCandidateBean(beanName);}}//handlerMethodsInitialized()只是日志工作//getHandlerMethods()handlerMethodsInitialized(getHandlerMethods());}

getCandidateBeanNames()

中上下文中獲取候選的bean

/*** Determine the names of candidate beans in the application context.* @since 5.1* @see #setDetectHandlerMethodsInAncestorContexts* @see BeanFactoryUtils#beanNamesForTypeIncludingAncestors*///從上下文中掃描合適的bean的名字protected String[] getCandidateBeanNames() {return (this.detectHandlerMethodsInAncestorContexts ?BeanFactoryUtils.beanNamesForTypeIncludingAncestors(obtainApplicationContext(), Object.class) :obtainApplicationContext().getBeanNamesForType(Object.class));}

processCandidateBean(String beanName)

/*** Determine the type of the specified candidate bean and call* {@link #detectHandlerMethods} if identified as a handler type.* <p>This implementation avoids bean creation through checking* {@link org.springframework.beans.factory.BeanFactory#getType}* and calling {@link #detectHandlerMethods} with the bean name.* @param beanName the name of the candidate bean* @since 5.1* @see #isHandler* @see #detectHandlerMethods*///發(fā)現(xiàn)并注冊(cè)handler methodsprotected void processCandidateBean(String beanName) {Class<?> beanType = null;try {//從上下文中獲取對(duì)應(yīng)beanName的bean的TypebeanType = obtainApplicationContext().getType(beanName);}catch (Throwable ex) {// An unresolvable bean type, probably from a lazy bean - let's ignore it.if (logger.isTraceEnabled()) {logger.trace("Could not resolve type for bean '" + beanName + "'", ex);}}//使用isHandler(Class<?> beanType)過濾符合要求的Handlerif (beanType != null && isHandler(beanType)) {//發(fā)現(xiàn)HandlerMethod,最終會(huì)調(diào)用父類方法注冊(cè)到this.mappingRegistry中detectHandlerMethods(beanName);}}

isHandler(Class<?> beanType)

判斷哪些是符合要求的Handler

//判斷哪些是符合要求的Handler,從該方法可以得知要的是@Controller和@RequestMapping的bean @Override protected boolean isHandler(Class<?> beanType) {return (AnnotatedElementUtils.hasAnnotation(beanType, Controller.class) ||AnnotatedElementUtils.hasAnnotation(beanType, RequestMapping.class)); }

detectHandlerMethods(Object handler)

發(fā)現(xiàn)HandlerMethod,最終會(huì)調(diào)用父類方法注冊(cè)到this.mappingRegistry中

/*** Look for handler methods in the specified handler bean.* @param handler either a bean name or an actual handler instance* @see #getMappingForMethod*///找handler bean中的handler methodsprotected void detectHandlerMethods(Object handler) {Class<?> handlerType = (handler instanceof String ?obtainApplicationContext().getType((String) handler) : handler.getClass());if (handlerType != null) {Class<?> userType = ClassUtils.getUserClass(handlerType);Map<Method, T> methods = MethodIntrospector.selectMethods(userType,(MethodIntrospector.MetadataLookup<T>) method -> {try {return getMappingForMethod(method, userType);}catch (Throwable ex) {throw new IllegalStateException("Invalid mapping on handler class [" +userType.getName() + "]: " + method, ex);}});if (logger.isTraceEnabled()) {logger.trace(formatMappings(userType, methods));}methods.forEach((method, mapping) -> {Method invocableMethod = AopUtils.selectInvocableMethod(method, userType); //核心是這個(gè),注冊(cè)HandlerMethod到mapping中registerHandlerMethod(handler, invocableMethod, mapping);});}}

getHandlerMethods()

獲取已經(jīng)注冊(cè)的Handler,你會(huì)發(fā)現(xiàn)HandlerMethod

/*** Return a (read-only) map with all mappings and HandlerMethod's.*/ public Map<T, HandlerMethod> getHandlerMethods() {this.mappingRegistry.acquireReadLock();try {return Collections.unmodifiableMap(this.mappingRegistry.getMappings());}finally {this.mappingRegistry.releaseReadLock();} }

找到RequestMappingHandlerMapping的兩個(gè)register方法,看看他注冊(cè)了什么:

  • registerMapping(RequestMappingInfo mapping, Object handler, Method method)
  • registerHandlerMethod(Object handler, Method method, RequestMappingInfo mapping)

你會(huì)發(fā)現(xiàn)兩個(gè)register方法主要是調(diào)用父類的register方法,并且跟新RequestMappingInfo中的ConsumesCondition,

//一個(gè)RequestMappingInfo對(duì)象(點(diǎn)開會(huì)發(fā)現(xiàn)各種XXXRequestCondition) //一個(gè)handler //一個(gè)method,調(diào)用的方法 @Override public void registerMapping(RequestMappingInfo mapping, Object handler, Method method) {//注冊(cè),最終會(huì)注冊(cè)到this.mappingRegistry中super.registerMapping(mapping, handler, method);//updateConsumesCondition主要是將method中形參列表加到RequestMappingInfo中的ConsumesConditionupdateConsumesCondition(mapping, method); }@Override protected void registerHandlerMethod(Object handler, Method method, RequestMappingInfo mapping) {super.registerHandlerMethod(handler, method, mapping);updateConsumesCondition(mapping, method); }

AbstractHandlerMapping

AbstractHandlerMapping是AbstractHandlerMethodMapping父類。

AbstractHandlerMapping提供了getHandler(HttpServletRequest request)用于獲取HandlerExecutionChain(Handler) ,所以RequestMappingHandlerMapping最終獲取的HandlerExecutionChain來自AbstractHandlerMapping提供的getHandler(HttpServletRequest request)

/*** Look up a handler for the given request, falling back to the default* handler if no specific one is found.* @param request current HTTP request* @return the corresponding handler instance, or the default handler* @see #getHandlerInternal*/@Override@Nullablepublic final HandlerExecutionChain getHandler(HttpServletRequest request) throws Exception {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;handler = obtainApplicationContext().getBean(handlerName);}HandlerExecutionChain executionChain = getHandlerExecutionChain(handler, request);if (logger.isTraceEnabled()) {logger.trace("Mapped to " + handler);}else if (logger.isDebugEnabled() && !request.getDispatcherType().equals(DispatcherType.ASYNC)) {logger.debug("Mapped to " + executionChain.getHandler());}if (hasCorsConfigurationSource(handler) || CorsUtils.isPreFlightRequest(request)) {CorsConfiguration config = (this.corsConfigurationSource != null ? this.corsConfigurationSource.getCorsConfiguration(request) : null);CorsConfiguration handlerConfig = getCorsConfiguration(handler, request);config = (config != null ? config.combine(handlerConfig) : handlerConfig);executionChain = getCorsHandlerExecutionChain(request, executionChain, config);}return executionChain;}

總結(jié)

以上是生活随笔為你收集整理的spring MVC RequestMappingHandlerMapping解析的全部?jī)?nèi)容,希望文章能夠幫你解決所遇到的問題。

如果覺得生活随笔網(wǎng)站內(nèi)容還不錯(cuò),歡迎將生活随笔推薦給好友。