SpringMVC何时加载的controller里的mapping方法

2023-12-25 18:36:05 浏览数 (2)

疑问

其实我一直有一个疑问,因为我在跟自己写的controller的生命周期源码的时候,没有发现解析mapping的代码,然后我就在想,什么时候解析并加载的mapping呢???

结果是一个新的类 RequestMappingHandlerMapping ,惊呆了,我的小伙伴

源码跟进

我就从RequestMappingHandlerMapping的生命周期的afterPropertiesSet()方法讲起

代码语言:javascript复制
//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();
	}
代码语言:javascript复制
//AbstractHandlerMethodMapping
protected void initHandlerMethods() {
        //遍历所有的类
		for (String beanName : getCandidateBeanNames()) {
			if (!beanName.startsWith(SCOPED_TARGET_NAME_PREFIX)) {
                //当beanName为自定义的helloController时跟进去--->
				processCandidateBean(beanName);
			}
		}
		handlerMethodsInitialized(getHandlerMethods());
	}
代码语言:javascript复制
//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);
		}
代码语言:javascript复制
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类并解析

0 人点赞