前往小程序,Get更优阅读体验!
立即前往
首页
学习
活动
专区
工具
TVP
发布
社区首页 >专栏 >SpringMVC何时加载的controller里的mapping方法

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

作者头像
CBeann
发布2023-12-25 18:36:05
680
发布2023-12-25 18:36:05
举报
文章被收录于专栏:CBeann的博客CBeann的博客

疑问

其实我一直有一个疑问,因为我在跟自己写的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类并解析

本文参与?腾讯云自媒体分享计划,分享自作者个人站点/博客。
原始发表:2022-03-07,如有侵权请联系 cloudcommunity@tencent.com 删除

本文分享自 作者个人站点/博客?前往查看

如有侵权,请联系 cloudcommunity@tencent.com 删除。

本文参与?腾讯云自媒体分享计划? ,欢迎热爱写作的你一起参与!

评论
登录后参与评论
0 条评论
热度
最新
推荐阅读
目录
  • 疑问
  • 源码跟进
领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档
http://www.vxiaotou.com