升级SpringCloud到Hoxton.SR3后SpringMVC的端点路径映射不打印,分析和解决

升级SpringMVC到5.2.4版本后,发现启动时不再打印端点路径映射信息。新版本中,日志打印代码被移除,但通过调整日志级别至trace,可在AbstractHandlerMethodMapping类中重新启用路径映射日志。

摘要生成于 C知道 ,由 DeepSeek-R1 满血版支持, 前往体验 >

升级版本就是事多...

SpringMVC版本5.2.4.RELEASE

版本信息

升级前版本

SpringBootSpringCloudSpringMVC
2.0.6.RELEASEFinchley.SR2

5.0.10.RELEASE

升级后版本

SpringBootSpringCloudSpringMVC
2.2.5.RELEASEHoxton.SR3

5.2.4.RELEASE

 

升级版本后发现启动时SpringMVC框架的端点路径映射不打印了, 有时候开发的时候可能会看看是没有注册映射

源码分析

这是新版本的SpringMVC注册路径的地方, 这个地方在旧版本中会有logger.info()的路径映射的日志打印, 新版是直接将打印日志的代码给删除掉了...

org.springframework.web.servlet.handler.AbstractHandlerMethodMapping.MappingRegistry#register

public void register(T mapping, Object handler, Method method) {
			// Assert that the handler method is not a suspending one.
			if (KotlinDetector.isKotlinType(method.getDeclaringClass()) && KotlinDelegate.isSuspend(method)) {
				throw new IllegalStateException("Unsupported suspending handler method detected: " + method);
			}
			this.readWriteLock.writeLock().lock();
			try {
				HandlerMethod handlerMethod = createHandlerMethod(handler, method);
				validateMethodMapping(handlerMethod, mapping);
				this.mappingLookup.put(mapping, handlerMethod);

				List<String> directUrls = getDirectUrls(mapping);
				for (String url : directUrls) {
					this.urlLookup.add(url, mapping);
				}

				String name = null;
				if (getNamingStrategy() != null) {
					name = getNamingStrategy().getName(handlerMethod, mapping);
					addMappingName(name, handlerMethod);
				}

				CorsConfiguration corsConfig = initCorsConfiguration(handler, method, mapping);
				if (corsConfig != null) {
					this.corsLookup.put(handlerMethod, corsConfig);
				}

				this.registry.put(mapping, new MappingRegistration<>(mapping, handlerMethod, directUrls, name));
			}
			finally {
				this.readWriteLock.writeLock().unlock();
			}
		}

但是我向上找还是发现了打印路径映射日志的地方

org.springframework.web.servlet.handler.AbstractHandlerMethodMapping#detectHandlerMethods

/**
	 * Look for handler methods in the specified handler bean.
	 * @param handler either a bean name or an actual handler instance
	 * @see #getMappingForMethod
	 */
	protected 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);
				registerHandlerMethod(handler, invocableMethod, mapping);
			});
		}
	}

这里是对整个Controller类中包含的路径进行循环遍历注册的地方,

这里判断了是否打开trace级别的日志输出, 如果开启的话就会打印这个controller包含的所有路径映射(路径与方法), 这里在旧版本打印的只是controller包含的路径映射的数量

日志格式

2020-04-10 14:09:19.901  [ main:21367 ] - [TRACE ,,, ] c.x.s.a.c.WebMvcConfig$FeignRequestMappingHandlerMapping#detectHandlerMethods:284 - 
	c.x.s.i.c.ItemUnitController:
	{GET /item/itemUnit/findById}: findById(Long)
	{GET /item/itemUnit/loaderItemUnits}: loaderItemUnits()
	{GET /item/itemUnit/getItemUnit}: getItemUnit(Long)
	{GET /item/itemUnit/findUnitByName}: findUnitByName(String)
	{GET /item/itemUnit/findAllItemUnit}: loadItemUnit()

解决办法

修改配置类的日志级别为trace就好了

application.yml

logging:
  level:
    # 输出端点映射
    com.xxx.xxx.config.WebMvcConfig: trace

这里WebMvcConfig类是我们项目继承WebMvcConfigurationSupport做的一些自定义配置的类, 改成自己项目的mvc配置类就好了

怎么找自己的配置类?

在这句代码上下个断点 if (logger.isTraceEnabled()) {

断下来之后执行表达式logger.getName()得到的类名就是你的配置类名

 

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值