spring 3.1.1 mvc HanderMapping源码

https://my.oschina.net/zhangxufeng/blog/2177464

spring 3.1.1 mvc HanderMapping源码

RequestMappingHandlerMapping getMappingForMethod



	/**
* {@inheritDoc}
* Expects a handler to have a type-level @{@link Controller} annotation.
*/
@Override
protected boolean isHandler(Class<?> beanType) {
return AnnotationUtils.findAnnotation(beanType, Controller.class) != null;
} /**
* Uses method and type-level @{@link RequestMapping} annotations to create
* the RequestMappingInfo.
*
* @return the created RequestMappingInfo, or {@code null} if the method
* does not have a {@code @RequestMapping} annotation.
*
* @see #getCustomMethodCondition(Method)
* @see #getCustomTypeCondition(Class)
*/
@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;
}

AbstractHandlerMethodMapping


/**
* ApplicationContext initialization and handler method detection.
*/
@Override
public void initApplicationContext() throws ApplicationContextException {
super.initApplicationContext();
initHandlerMethods();
} /**
* Scan beans in the ApplicationContext, detect and register handler methods.
* @see #isHandler(Class)
* @see #getMappingForMethod(Method, Class)
* @see #handlerMethodsInitialized(Map)
*/
protected void initHandlerMethods() {
if (logger.isDebugEnabled()) {
logger.debug("Looking for request mappings in application context: " + getApplicationContext());
} String[] beanNames = (this.detectHandlerMethodsInAncestorContexts ?
BeanFactoryUtils.beanNamesForTypeIncludingAncestors(getApplicationContext(), Object.class) :
getApplicationContext().getBeanNamesForType(Object.class)); for (String beanName : beanNames) {
// 判断类上面是否有Controller 注解 如果有则查找它及它的方法是否有RequestMapping注解
if (isHandler(getApplicationContext().getType(beanName))){
detectHandlerMethods(beanName);
}
}
handlerMethodsInitialized(getHandlerMethods());
} /**
* Look for handler methods in a handler.
* @param handler the bean name of a handler or a handler instance
*/
protected void detectHandlerMethods(final Object handler) {
Class<?> handlerType = (handler instanceof String) ?
getApplicationContext().getType((String) handler) : handler.getClass(); final Class<?> userType = ClassUtils.getUserClass(handlerType); //把此类的方法里有RequestMapping注解的方法都找出来
Set<Method> methods = HandlerMethodSelector.selectMethods(userType, new MethodFilter() {
public boolean matches(Method method) {
return getMappingForMethod(method, userType) != null;
}
}); //将有RequestMapping注解的方法注册一下 handlerMethods urlMap RequestMappingInfo mapping
for (Method method : methods) {
T mapping = getMappingForMethod(method, userType);
registerHandlerMethod(handler, method, mapping);
}
} /**
* Provide the mapping for a handler method. A method for which no
* mapping can be provided is not a handler method.
*
* @param method the method to provide a mapping for
* @param handlerType the handler type, possibly a sub-type of the method's
* declaring class
* @return the mapping, or {@code null} if the method is not mapped
*/
protected abstract T getMappingForMethod(Method method, Class<?> handlerType); /**
* Register a handler method and its unique mapping.
*
* @param handler the bean name of the handler or the handler instance
* @param method the method to register
* @param mapping the mapping conditions associated with the handler method RequestMappingInfo mapping
* @throws IllegalStateException if another method was already registered
* under the same mapping
*/
protected void registerHandlerMethod(Object handler, Method method, T mapping) {
HandlerMethod handlerMethod;
if (handler instanceof String) {
String beanName = (String) handler;
handlerMethod = new HandlerMethod(beanName, getApplicationContext(), method);
}
else {
handlerMethod = new HandlerMethod(handler, method);
} HandlerMethod oldHandlerMethod = handlerMethods.get(mapping);
if (oldHandlerMethod != null && !oldHandlerMethod.equals(handlerMethod)) {
throw new IllegalStateException("Ambiguous mapping found. Cannot map '" + handlerMethod.getBean()
+ "' bean method \n" + handlerMethod + "\nto " + mapping + ": There is already '"
+ oldHandlerMethod.getBean() + "' bean method\n" + oldHandlerMethod + " mapped.");
} handlerMethods.put(mapping, handlerMethod);
if (logger.isInfoEnabled()) {
logger.info("Mapped \"" + mapping + "\" onto " + handlerMethod);
} Set<String> patterns = getMappingPathPatterns(mapping);
for (String pattern : patterns) {
if (!getPathMatcher().isPattern(pattern)) {
urlMap.add(pattern, mapping);
}
}
}

RequestMappingInfoHandlerMapping


/**
* Get the URL path patterns associated with this {@link RequestMappingInfo}.
*/
@Override
protected Set<String> getMappingPathPatterns(RequestMappingInfo info) {
return info.getPatternsCondition().getPatterns();
}
上一篇:如何从零开始系统化学习视觉SLAM?


下一篇:Spark 实践——用 Scala 和 Spark 进行数据分析