接口定义
/**
* Interface to be implemented by objects that define a mapping between
* requests and handler objects.
*/
public interface HandlerMapping {
//根据request获取处理链
HandlerExecutionChain getHandler(HttpServletRequest request) throws Exception;
}
以RequestMappingHandlerMapping为例来讲
RequestMappingHandlerMapping初始化过程
定义: 请求路径-处理过程映射管理
打个比方就是根据你的http请求的路径得到可以处理的handler(你的Controller方法)
先看下他的继承关系
看到3个Spring的生命周期接口
-
ServletContextAware:保存ServletContext
#org.springframework.web.context.support.WebApplicationObjectSupport @Override public final void setServletContext(ServletContext servletContext) { if (servletContext != this.servletContext) { //保存ServletContext this.servletContext = servletContext; if (servletContext != null) { //空实现 initServletContext(servletContext); } } }
-
ApplicationContext:保存Spring上下文
@Override public final void setApplicationContext(ApplicationContext context) throws BeansException { ... //保存SpringMVC上下文 this.applicationContext = context; //保存资源访问器 this.messageSourceAccessor = new MessageSourceAccessor(context); //空实现 initApplicationContext(context); ... }
-
InitlizingBean:初始化映射关系
#org.springframework.web.servlet.mvc.method.annotation.RequestMappingHandlerMapping //1. @Override public void afterPropertiesSet() { if (this.useRegisteredSuffixPatternMatch) { this.fileExtensions.addAll(this.contentNegotiationManager.getAllFileExtensions()); } super.afterPropertiesSet(); } //4. @Override protected boolean isHandler(Class<?> beanType) { return ((AnnotationUtils.findAnnotation(beanType, Controller.class) != null) || (AnnotationUtils.findAnnotation(beanType, RequestMapping.class) != null)); } //6. @Override protected RequestMappingInfo getMappingForMethod(Method method, Class<?> handlerType) { RequestMappingInfo info = null; RequestMapping methodAnnotation = AnnotationUtils.findAnnotation(method, RequestMapping.class); if (methodAnnotation != null) { //组装映射信息 RequestCondition<?> methodCondition = getCustomMethodCondition(method); info = createRequestMappingInfo(methodAnnotation, methodCondition); RequestMapping typeAnnotation = AnnotationUtils.findAnnotation(handlerType, RequestMapping.class); if (typeAnnotation != null) { RequestCondition<?> typeCondition = getCustomTypeCondition(handlerType); info = createRequestMappingInfo(typeAnnotation, typeCondition).combine(info); } } return info; } #org.springframework.web.servlet.handler.AbstractHandlerMethodMapping //2. @Override public void afterPropertiesSet() { initHandlerMethods(); } //3. protected void initHandlerMethods() { if (logger.isDebugEnabled()) { logger.debug("Looking for request mappings in application context: " + getApplicationContext()); } //从容器中获取所有object类型名 String[] beanNames = (this.detectHandlerMethodsInAncestorContexts ? BeanFactoryUtils.beanNamesForTypeIncludingAncestors(getApplicationContext(), Object.class) : getApplicationContext().getBeanNamesForType(Object.class)); for (String beanName : beanNames) { //抽象,过滤(在RequestMappingHandlerMapping中根据Controller和RequestMapping注解过滤) if (!beanName.startsWith(SCOPED_TARGET_NAME_PREFIX) && isHandler(getApplicationContext().getType(beanName))){ //探测类中定义的handler方法 detectHandlerMethods(beanName); } } handlerMethodsInitialized(getHandlerMethods()); } //5. protected void detectHandlerMethods(final Object handler) { Class<?> handlerType = (handler instanceof String ? getApplicationContext().getType((String) handler) : handler.getClass()); final Map<Method, T> mappings = new IdentityHashMap<Method, T>(); final Class<?> userType = ClassUtils.getUserClass(handlerType); //得到符合条件的handler方法 Set<Method> methods = HandlerMethodSelector.selectMethods(userType, new MethodFilter() { @Override public boolean matches(Method method) { //抽象,得到映射信息(如RequestMappingInfo) T mapping = getMappingForMethod(method, userType); if (mapping != null) { mappings.put(method, mapping); return true; } else { return false; } } }); //注册handler映射关系 for (Method method : methods) { //保存映射路径和处理方法(还有跨域信息) registerHandlerMethod(handler, method, mappings.get(method)); } }
过程概括:
-
获取所有object子类
-
根据条件过滤出handle处理类
-
解析handle类中定义的处理方法
-
注册映射关系
public void register(T mapping, Object handler, Method method) { try { //保存handler和处理方法 HandlerMethod handlerMethod = createHandlerMethod(handler, method); ... //保存映射路径和HandlerMethod this.mappingLookup.put(mapping, handlerMethod); //解析@CrossOrigin配置(跨域用) CorsConfiguration corsConfig = initCorsConfiguration(handler, method, mapping); //保存跨域信息 if (corsConfig != null) { this.corsLookup.put(handlerMethod, corsConfig); } //保存映射关系 this.registry.put(mapping, new MappingRegistration<T>(mapping, handlerMethod, directUrls, name)); } ...
}
## getHandler()实现
```java
#org.springframework.web.servlet.handler.AbstractHandlerMapping
@Override
public final HandlerExecutionChain getHandler(HttpServletRequest request) throws Exception {
//抽象,调用子类实现得到一个handler(可以是任一对象,需要通过HandleAdapter来解析)
//RequestMappingInfoHandlerMapping中具体实现就是匹配请求路径和RequestMapping注解
Object handler = getHandlerInternal(request);
...
//包装handle成HandlerExecutionChain
HandlerExecutionChain executionChain = getHandlerExecutionChain(handler, request);
//如果是跨域请求 则根据@CrossOrigin配置添加前置Intercept
if (CorsUtils.isCorsRequest(request)) {
CorsConfiguration globalConfig = this.corsConfigSource.getCorsConfiguration(request);
CorsConfiguration handlerConfig = getCorsConfiguration(handler, request);
CorsConfiguration config = (globalConfig != null ? globalConfig.combine(handlerConfig) : handlerConfig);
executionChain = getCorsHandlerExecutionChain(request, executionChain, config);
}
return executionChain;
}
#org.springframework.web.servlet.handler.AbstractHandlerMethodMapping
@Override
protected HandlerMethod getHandlerInternal(HttpServletRequest request) throws Exception {
//得到映射路径
String lookupPath = getUrlPathHelper().getLookupPathForRequest(request);
...
try {
//根据映射路径获取HandlerMethod
HandlerMethod handlerMethod = lookupHandlerMethod(lookupPath, request);
return (handlerMethod != null ? handlerMethod.createWithResolvedBean() : null);
}
...
}