升級版本就是事多...
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()得到的類名就是你的配置類名