升级版本就是事多...
SpringMVC版本5.2.4.RELEASE
版本信息
升级前版本
SpringBoot | SpringCloud | SpringMVC |
2.0.6.RELEASE | Finchley.SR2 | 5.0.10.RELEASE |
升级后版本
SpringBoot | SpringCloud | SpringMVC |
2.2.5.RELEASE | Hoxton.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()得到的类名就是你的配置类名