家资是何物,积帙列梁梠。这篇文章主要讲述spring mvc HanderMapping源码相关的知识,希望能为你提供帮助。
https://my.oschina.net/zhangxufeng/blog/2177464
文章图片
RequestMappingHandlerMappinggetMappingForMethod
/**
* {@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注解的方法注册一下handlerMethodsurlMapRequestMappingInfo 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 methodRequestMappingInfo 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);
}
}
}
【spring mvc HanderMapping源码】RequestMappingInfoHandlerMapping
/**
* Get the URL path patterns associated with this {@link RequestMappingInfo}.
*/
@Override
protected Set<
String>
getMappingPathPatterns(RequestMappingInfo info) {
return info.getPatternsCondition().getPatterns();
}
推荐阅读
- 运行流畅快速不卡顿的第三方Android模拟器的安装及配置——夜神模拟器
- Android SDK下载与安装
- 基于android的天气预报的设计与实现
- 查看apk安装包的AndroidManifest.xml文件
- HibernateUnable to locate appropriate constructor on class原因分析
- 安卓圆角背景遮罩。覆盖实现方式(适用于所有控件)
- 通用mapper中的select方法的注意点
- Dapper基础知识三
- Dapper基础知识二