demo下载
Demooo/springmvc-demo-app at master · cbeann/Demooo · GitHub
源码跟进
我就从RequestMappingHandlerMapping的生命周期的afterPropertiesSet()方法讲起
//RequestMappingHandlerMapping @Override public void afterPropertiesSet() { this.config = new RequestMappingInfo.BuilderConfiguration(); this.config.setUrlPathHelper(getUrlPathHelper()); this.config.setPathMatcher(getPathMatcher()); this.config.setSuffixPatternMatch(this.useSuffixPatternMatch); this.config.setTrailingSlashMatch(this.useTrailingSlashMatch); this.config.setRegisteredSuffixPatternMatch(this.useRegisteredSuffixPatternMatch); this.config.setContentNegotiationManager(getContentNegotiationManager()); //调用父类的方法,跟进去---> super.afterPropertiesSet(); }
//AbstractHandlerMethodMapping protected void initHandlerMethods() { //遍历所有的类 for (String beanName : getCandidateBeanNames()) { if (!beanName.startsWith(SCOPED_TARGET_NAME_PREFIX)) { //当beanName为自定义的helloController时跟进去---> processCandidateBean(beanName); } } handlerMethodsInitialized(getHandlerMethods()); }
//AbstractHandlerMethodMapping 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 (logger.isTraceEnabled()) { logger.trace("Could not resolve type for bean '" + beanName + "'", ex); } } //如果此类上有Controller或者RequestMapping,则返回真 if (beanType != null && isHandler(beanType)) { //跟进去---> detectHandlerMethods(beanName); }
AbstractHandlerMethodMapping protected void detectHandlerMethods(Object handler) { Class<?> handlerType = (handler instanceof String ? obtainApplicationContext().getType((String) handler) : handler.getClass()); if (handlerType != null) { Class<?> userType = ClassUtils.getUserClass(handlerType); //解析类并且获取所有带有requestMapping的方法 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)); } //此时将method和mapping都注入到某个地方(map)中,后面就可以直接使用了 methods.forEach((method, mapping) -> { Method invocableMethod = AopUtils.selectInvocableMethod(method, userType); registerHandlerMethod(handler, invocableMethod, mapping); }); } }
此时就已经明白了,并不是在自定义的controller类的生命周期内解析的mapping,而是在RequestMappingHandlerMapping 生命周期的afterPropertiesSet()方法中获取所有的controller类并解析