SpringMVC之HandlerMapping
HandlerMapping
顾名思义,是处理器映射器,SpringMVC中配置的所有的HandlerMapping
都维护在DispatcherServlet
t对象中的hadlerMappings
属性中,在DispatcherServlet.doDispatch
中打个断点,执行this.getHandlerMappings()
语句可以得到所有的HandlerMapping
如果加了@EnableWebMvc注解,SpringMVC默认加载了四个HandlerMapping,分别为:RequestMappingHandlerMapping、BeanNameUrlHandlerMapping、RouterFunctionMapping、SimpleUrlHandlerMapping
- RequestMappingHandlerMapping:详细讲解
- BeanNameUrlHandlerMapping:扫描实现了Controller接口的处理器,将这些处理器的beanName作为url的匹配模板
- RouterFunctionMapping:
- SimpleUrlHandlerMapping:根据路径直接匹配,SpringMVC默认用这个映射器映射静态资源
RequestMappingHandlerMapping详解
RequestMappingHandlerMapping
是SpringMVC中优先级最高且用的最多的一个处理器映射器,默认在WebMvcConfigurationSupport类中被加载,可以根据RequestMapping中的路径模板匹配
以下是RequestMappingHandlerMapping初始化核心代码
protected void initHandlerMethods() {
// getCandidateBeanNames获取到的是Spring中所有bean的名称
for (String beanName : getCandidateBeanNames()) {
// 如果是一个处理器类 -> 去探测HandlerMethods
if (beanType != null && isHandler(beanType)) {
detectHandlerMethods(beanName);
}
}
handlerMethodsInitialized(getHandlerMethods());
}
protected boolean isHandler(Class<?> beanType) {
// 如果这个类上有@Controller注解或@RequestMapping注解,那么就是一个处理器类
return (AnnotatedElementUtils.hasAnnotation(beanType, Controller.class) ||AnnotatedElementUtils.hasAnnotation(beanType, RequestMapping.class));
}
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标识的方法并转化为一个Mapping对象(包括方法对象,请求路径,请求方式等)
Map<Method, T> methods = MethodIntrospector.selectMethods(userType, (MethodIntrospector.MetadataLookup<T>) method -> return getMappingForMethod(method, userType));
// 将这些映射转换为HandlerMethod对象并注册
methods.forEach((method, mapping) -> {
Method invocableMethod = AopUtils.selectInvocableMethod(method, userType);
registerHandlerMethod(handler, invocableMethod, mapping);
});
}
}