之前面试苏小研的时候面试官问了一个很有意思的问题,前端传给后端一个URL,后端可以通过控制器进行映射,那后端是如何存储映射的URL的?
1.首先在spring boot项目启动的时候会初始化很多组件,会通过一个isHander方法来判断文件是否是一个控制器映射文件(主要是通过@Controller和@RequestMapping注解来判断)。
2.通过解析method方法提取匹配条件,每一个method会生成一个HandlerMethod。然后生成一个map映射。
// 匹配条件到HandlerMethod的映射
private final Map<T, HandlerMethod> handlerMethods = new LinkedHashMap<T, HandlerMethod>();
3.根据URL生成匹配条件到URL的映射map
// url到匹配条件的映射
private final MultiValueMap<String, T> urlMap = new LinkedMultiValueMap<String, T>();
这里的key是URL,value是匹配条件集合,因为一个URL可能对应不同的处理方法(restful编程风格)
后端收到前端的一个URL,首先会根据url到匹配条件的映射Map取到匹配条件集合,然后通过匹配具体信息进行比对。
具体代码:
容器中的bean初始化时进行处理
RequestMappingHandlerMapping是其实现类,InitializingBean接口实现类会在容器bean实例化后调用初始化方法,具体的可以去看bean生命周期和容器启动流程,这里只需要知道spring启动的时候会自己去调用这个方法然后遍历容器中的所有类就好
RequestMappingHandlerMapping
遍历容器中的类判断是否被@Controller或者@RequestMapping注解标注。
调用AbstractHandlerMethodMapping.MappingRegistry.register方法注册
AbstractHandlerMethodMapping.MappingRegistry
mappingLookup存储的是匹配条件和具体方法的映射,
urlLookup存储的是url和匹配条件的映射。