RequestMappingHandlerMapping负责将RequestMapping注解的方法与url关联起来,并且返回HandlerExecutionChain
加载过程
DispatcherServlet.initStrategies的initHandlerMappings方法中会通过读取DispatchServerlet.proeprties对HandlerMapping进行初始化,这里重点看RequestMappingHandlerMapping类
DispatcherServlet.properties的值
1 | org.springframework.web.servlet.HandlerMapping=org.springframework.web.servlet.handler.BeanNameUrlHandlerMapping,\ |
初始化HandlerMapping
HandlerMapping,封装了是request与他的处理类HandlerMethod的映射关系,他的职责主要是通过request找到对应的handlerMapping
AbstractHandlerMethodMapping实现了InitializingBean所以在afterPropertiesSet会进行初始化工作
1 | public void afterPropertiesSet() { |
重点方法:processCandidateBean
根据bean找到method,封装成handlerMethod注册到容器中
1 | protected void processCandidateBean(String beanName) { |
重点方法
detectHandlerMethods遍历bean的method方法
1 | protected void detectHandlerMethods(Object handler) { |
重点方法:registerHandlerMethod(handler, invocableMethod, mapping)
向容器注册HandlerMapping:registerHandlerMethod(handler, invocableMethod, mapping);
这里的mappingRegistry 是AbstractHandlerMethodMapping的内部类MappingRegistry;
1 | protected void registerHandlerMethod(Object handler, Method method, T mapping) { |
至此所有的RequestMapping都注册到容器中
doDipatch时候
通过reqeust获取handler和拦截器封装成HandlerExecutionChain过程
找到在初始化时候注册的handlerMappings,调用它们的getHandler方法,具体实现在AbstraceHanlderMapping中
1 | public final HandlerExecutionChain getHandler(HttpServletRequest request) throws Exception { |
重点方法1 getHandlerInternal
这里的实现见:AbstractHandlerMethodMapping.getgetHandlerInternal
1 |
|
重点方法2 getHandlerExecutionChain
返回handler和拦截器的封装,注:springboot的WebMvcConfigurer.addInterceptors方法中添加的拦截器会转成MappedInterceptor添加到RRequestMappingHandlerMapping中代码可以从WebMvcAutoConfiguration中看
1 | protected HandlerExecutionChain getHandlerExecutionChain(Object handler, HttpServletRequest request) { |
返回了包含handler和interceptor的HandlerExecutionChain为下一步handlerAdapter执行做好准备
附录:MappingRegistry几个重要的容器
上面提到的register过程中涉及到了MappingRegistry类,它包含了几个重要容器用来缓存url,RequestMappingInfo HandlerMethod的对应关系
- urlLookup: url–>List<RequestMappingInfo>
- mappingLookup:RequestMappingInfo–>HandlerMethod
附录:@RequestMapping注解
RequestMapping是一个用来处理请求地址映射的注解,可用于类或方法上。用于类上,表示类中的所有响应请求的方法都是以该地址作为父路径。
- value:指定请求的实际地址,指定的地址可以是URI Template 模式(后面将会说明);
- method:指定请求的method类型, GET、POST、PUT、DELETE等;
- consumes:指定处理请求的提交内容类型(Content-Type),例如application/json, text/html;
- produces:指定返回的内容类型,仅当request请求头中的(Accept)类型中包含该指定类型才返回;
- params:指定request中必须包含某些参数值是,才让该方法处理。
- headers:指定request中必须包含某些指定的header值,才能让该方法处理请求。