/** * 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为例来说java
定义: 请求路径-处理过程映射管理web
打个比方就是根据你的http请求的路径获得能够处理的handler(你的Controller方法)spring
先看下他的继承关系跨域
看到3个Spring的生命周期接口bash
ServletContextAware:保存ServletContextmvc
#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上下文app
@Override
public final void setApplicationContext(ApplicationContext context) throws BeansException {
...
//保存SpringMVC上下文
this.applicationContext = context;
//保存资源访问器
this.messageSourceAccessor = new MessageSourceAccessor(context);
//空实现
initApplicationContext(context);
...
}
复制代码
InitlizingBean:初始化映射关系cors
#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));
}
}
复制代码
过程归纳:ide
获取全部object子类ui
根据条件过滤出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);
}
...
}
复制代码