Spring的RequestMappingHandlerMapping详解

深刻理解IdentityHashMap:[url]http://donald-draper.iteye.com/blog/2326264[/url]
深入理解Collections的unmodifiableMap(Map map)方法:[url]http://donald-draper.iteye.com/blog/2326291[/url]
Spring-RequestMappingHandlerAdapter初始化及请求处理:[url]http://donald-draper.iteye.com/blog/2326185[/url]
我们来看DispatcherServlet的handlerMappings初始化所做的事情
public class DispatcherServlet extends FrameworkServlet
{
public DispatcherServlet(WebApplicationContext webApplicationContext)
{
super(webApplicationContext);
detectAllHandlerMappings = true;
detectAllHandlerAdapters = true;
detectAllHandlerExceptionResolvers = true;
detectAllViewResolvers = true;
throwExceptionIfNoHandlerFound = false;
cleanupAfterInclude = true;
}

//初始化控制器映射
private void initHandlerMappings(ApplicationContext context)
{
handlerMappings = null;
if(detectAllHandlerMappings)
{
Map matchingBeans = BeanFactoryUtils.beansOfTypeIncludingAncestors(context, org/springframework/web/servlet/HandlerMapping, true, false);
if(!matchingBeans.isEmpty())
{
//List<HashMap<String,HandlerMapping>>,Key为beanName,value值为HandlerMapping实例
handlerMappings = new ArrayList(matchingBeans.values());
OrderComparator.sort(handlerMappings);
}
}
}
//初始化控制器方法适配器
private void initHandlerAdapters(ApplicationContext context)
{
handlerAdapters = null;
if(detectAllHandlerAdapters)
{
Map matchingBeans = BeanFactoryUtils.beansOfTypeIncludingAncestors(context, org/springframework/web/servlet/HandlerAdapter, true, false);
if(!matchingBeans.isEmpty())
{
//List<HashMap<String,HandlerAdapter>>,Key为beanName,value值为HandlerAdapter实例
handlerAdapters = new ArrayList(matchingBeans.values());
OrderComparator.sort(handlerAdapters);
}
}
}

private List handlerMappings;//List<HashMap<String,HandlerMapping>>,Key为beanName,value值为HandlerMapping实例
private List handlerAdapters;//List<HashMap<String,HandlerAdapter>>,Key为beanName,value值为HandlerAdapter实例
private List handlerExceptionResolvers;
private List viewResolvers;

static
{
try
{
//加载默认配置文件
ClassPathResource resource = new ClassPathResource("DispatcherServlet.properties", org/springframework/web/servlet/DispatcherServlet);
defaultStrategies = PropertiesLoaderUtils.loadProperties(resource);
}
}
}

//Spring日志追踪我们可以发现,DispatcherServletd的控制器映射处理器为
org.springframework.web.servlet.mvc.method.annotation.RequestMappingHandlerMapping
org.springframework.web.servlet.handler.BeanNameUrlHandlerMapping
org.springframework.web.servlet.handler.SimpleUrlHandlerMapping
这里我们来看RequestMappingHandlerMapping
public class RequestMappingHandlerMapping extends RequestMappingInfoHandlerMapping
implements EmbeddedValueResolverAware
{
//初始化
public void afterPropertiesSet()
{
if(useRegisteredSuffixPatternMatch)
fileExtensions.addAll(contentNegotiationManager.getAllFileExtensions());
//调用父类的初始化
super.afterPropertiesSet();
}
private boolean useSuffixPatternMatch;
private boolean useRegisteredSuffixPatternMatch;
private boolean useTrailingSlashMatch;
private ContentNegotiationManager contentNegotiationManager;
private final List fileExtensions = new ArrayList();
private StringValueResolver embeddedValueResolver;
}
来查看AbstractHandlerMethodMapping
public abstract class AbstractHandlerMethodMapping extends AbstractHandlerMapping
implements InitializingBean
{
//初始化
public void afterPropertiesSet()
{
//委托给initHandlerMethods
initHandlerMethods();
}
//初始化方法处理器
protected void initHandlerMethods()
{
//获取所有bean容器的beanName
String beanNames[] = detectHandlerMethodsInAncestorContexts ?
BeanFactoryUtils.beanNamesForTypeIncludingAncestors(getApplicationContext(), java/lang/Object) :
getApplicationContext().getBeanNamesForType(java/lang/Object);
String as[] = beanNames;
int i = as.length;
for(int j = 0; j < i; j++)
{
String beanName = as[j];
//如果bean为Controller
if(!beanName.startsWith("scopedTarget.") && isHandler(getApplicationContext().getType(beanName)))
//
detectHandlerMethods(beanName);
}
handlerMethodsInitialized(getHandlerMethods());
}
//获取方法处理器Map
public Map getHandlerMethods()
{
//返回一个不可修改的Map集
return Collections.unmodifiableMap(handlerMethods);
}
//留给子类扩展
protected void handlerMethodsInitialized(Map map)
{ }
//委托给RequestMappingHandlerMapping
protected abstract boolean isHandler(Class class1);
//将handler带@RequestMapping的方法添加到方法处理器Map中handlerMethods,及路径映射Map中urlMap
protected void detectHandlerMethods(Object handler)
{
Class handlerType = (handler instanceof String) ? getApplicationContext().getType((String)handler) : handler.getClass();
//注意这里用的是IdentityHashMap
final Map mappings = new IdentityHashMap();
final Class userType = ClassUtils.getUserClass(handlerType);
//获取Contoller所有带@RequestMapping的方法
Set methods = HandlerMethodSelector.selectMethods(userType, new org.springframework.util.ReflectionUtils.MethodFilter() {
public boolean matches(Method method)
{

//获取handlerType的method的@RequestMapping注解信息
Object mapping = getMappingForMethod(method, userType);
if(mapping != null)
{
mappings.put(method, mapping);
return true;
} else
{
return false;
}
}
final Class val$userType;
final Map val$mappings;
final AbstractHandlerMethodMapping this$0;
{
this.this$0 = AbstractHandlerMethodMapping.this;
userType = class1;
mappings = map;
super();
}
});
Method method;
for(Iterator iterator = methods.iterator(); iterator.hasNext();
registerHandlerMethod(handler, method, mappings.get(method)))
method = (Method)iterator.next();
}
protected void registerHandlerMethod(Object handler, Method method, Object mapping)
{
//创建方法处理器
HandlerMethod newHandlerMethod = createHandlerMethod(handler, method);
//从handlerMethods中获取方法处理器信息根据@RequestMapping注解信息
HandlerMethod oldHandlerMethod = (HandlerMethod)handlerMethods.get(mapping);
//如果已经存在,则抛出不能映射异常
if(oldHandlerMethod != null && !oldHandlerMethod.equals(newHandlerMethod))
throw new IllegalStateException((new StringBuilder()).append("Ambiguous mapping found. Cannot map '").append(newHandlerMethod.getBean()).append("' bean method \n").append(newHandlerMethod).append("\nto ").append(mapping).append(": There is already '").append(oldHandlerMethod.getBean()).append("' bean method\n").append(oldHandlerMethod).append(" mapped.").toString());
//将方法处理器放入handlerMethods中
handlerMethods.put(mapping, newHandlerMethod);
if(logger.isInfoEnabled())
logger.info((new StringBuilder()).append("Mapped \"").append(mapping).append("\" onto ").append(newHandlerMethod).toString());
//获取路径集
Set patterns = getMappingPathPatterns(mapping);
Iterator iterator = patterns.iterator();
do
{
if(!iterator.hasNext())
break;
String pattern = (String)iterator.next();
if(!getPathMatcher().isPattern(pattern))
//将路径与mapping关联
urlMap.add(pattern, mapping);
} while(true);
}
//委托给RequestMappingInfoHandlerMapping
protected abstract Object getMappingForMethod(Method method, Class class1);
protected abstract Set getMappingPathPatterns(Object obj);
//根据request的url寻找合适的HandlerMethod
protected HandlerMethod getHandlerInternal(HttpServletRequest request)
throws Exception
{
String lookupPath = getUrlPathHelper().getLookupPathForRequest(request);
if(logger.isDebugEnabled())
logger.debug((new StringBuilder()).append("Looking up handler method for path ").append(lookupPath).toString());
//根据路径和request寻找handlerMethod
HandlerMethod handlerMethod = lookupHandlerMethod(lookupPath, request);
if(logger.isDebugEnabled())
if(handlerMethod != null)
logger.debug((new StringBuilder()).append("Returning handler method [").append(handlerMethod).append("]").toString());
else
logger.debug((new StringBuilder()).append("Did not find handler method for [").append(lookupPath).append("]").toString());
return handlerMethod == null ? null : handlerMethod.createWithResolvedBean();
}
//根据路径和request寻找handlerMethod
protected HandlerMethod lookupHandlerMethod(String lookupPath, HttpServletRequest request)
throws Exception
{
List matches = new ArrayList();
List directPathMatches = (List)urlMap.get(lookupPath);
if(directPathMatches != null)
addMatchingMappings(directPathMatches, matches, request);
if(matches.isEmpty())
addMatchingMappings(handlerMethods.keySet(), matches, request);
if(!matches.isEmpty())
{
Comparator comparator = new MatchComparator(getMappingComparator(request));
Collections.sort(matches, comparator);
if(logger.isTraceEnabled())
logger.trace((new StringBuilder()).append("Found ").append(matches.size()).append(" matching mapping(s) for [").append(lookupPath).append("] : ").append(matches).toString());
Match bestMatch = (Match)matches.get(0);
if(matches.size() > 1)
{
Match secondBestMatch = (Match)matches.get(1);
if(comparator.compare(bestMatch, secondBestMatch) == 0)
{
Method m1 = bestMatch.handlerMethod.getMethod();
Method m2 = secondBestMatch.handlerMethod.getMethod();
throw new IllegalStateException((new StringBuilder()).append("Ambiguous handler methods mapped for HTTP path '").append(request.getRequestURL()).append("': {").append(m1).append(", ").append(m2).append("}").toString());
}
}
handleMatch(bestMatch.mapping, lookupPath, request);
return bestMatch.handlerMethod;
} else
{
return handleNoMatch(handlerMethods.keySet(), lookupPath, request);
}
}
private static final String SCOPED_TARGET_NAME_PREFIX = "scopedTarget.";
private boolean detectHandlerMethodsInAncestorContexts;
//LinkedHashMap<RequestMappingInfo,HandlerMethod>
private final Map handlerMethods = new LinkedHashMap();
/LinkedHashMap<String,RequestMappingInfo>,key为路径
private final MultiValueMap urlMap = new LinkedMultiValueMap();
}

查看RequestMappingHandlerMapping.isHandler()
//isHandler,判断bean是否带有@Controller
 protected boolean isHandler(Class beanType)
{
return AnnotationUtils.findAnnotation(beanType, org/springframework/stereotype/Controller) != null || AnnotationUtils.findAnnotation(beanType, org/springframework/web/bind/annotation/RequestMapping) != null;
}

查看RequestMappingHandlerMapping.getMappingForMethod()
protected volatile Object getMappingForMethod(Method method, Class class1)
{
return getMappingForMethod(method, class1);
}

//判断handlerType的method是否带@RequestMapping,并返回注解信息
protected RequestMappingInfo getMappingForMethod(Method method, Class handlerType)
{
RequestMappingInfo info = null;
RequestMapping methodAnnotation = (RequestMapping)AnnotationUtils.findAnnotation(method,
org/springframework/web/bind/annotation/RequestMapping);
if(methodAnnotation != null)
{
RequestCondition methodCondition = getCustomMethodCondition(method);
info = createRequestMappingInfo(methodAnnotation, methodCondition);
RequestMapping typeAnnotation = (RequestMapping)AnnotationUtils.findAnnotation(handlerType, org/springframework/web/bind/annotation/RequestMapping);
if(typeAnnotation != null)
{
RequestCondition typeCondition = getCustomTypeCondition(handlerType);
info = createRequestMappingInfo(typeAnnotation, typeCondition).combine(info);
}
}
return info;
}

查看RequestMappingInfoHandlerMapping.getMappingPathPatterns()
public abstract class RequestMappingInfoHandlerMapping extends AbstractHandlerMethodMapping
{
protected Set getMappingPathPatterns(RequestMappingInfo info)
{
return info.getPatternsCondition().getPatterns();
}
}

//RequestMappingInfo
public final class RequestMappingInfo
implements RequestCondition
{
public PatternsRequestCondition getPatternsCondition()
{
return patternsCondition;
}
private final PatternsRequestCondition patternsCondition;
private final RequestMethodsRequestCondition methodsCondition;
private final ParamsRequestCondition paramsCondition;
private final HeadersRequestCondition headersCondition;
private final ConsumesRequestCondition consumesCondition;
private final ProducesRequestCondition producesCondition;
private final RequestConditionHolder customConditionHolder;
}

查看PatternsRequestCondition
public final class PatternsRequestCondition extends AbstractRequestCondition
{
public Set getPatterns()
{
return patterns;
}
private final Set patterns;
private final UrlPathHelper pathHelper;
private final PathMatcher pathMatcher;
private final boolean useSuffixPatternMatch;
private final boolean useTrailingSlashMatch;
private final List fileExtensions;
}

//RequestMappingInfo
public final class RequestMappingInfo
implements RequestCondition
{
public PatternsRequestCondition getPatternsCondition()
{
return patternsCondition;
}
private final PatternsRequestCondition patternsCondition;
private final RequestMethodsRequestCondition methodsCondition;
private final ParamsRequestCondition paramsCondition;
private final HeadersRequestCondition headersCondition;
private final ConsumesRequestCondition consumesCondition;
private final ProducesRequestCondition producesCondition;
private final RequestConditionHolder customConditionHolder;
}

查看PatternsRequestCondition
public final class PatternsRequestCondition extends AbstractRequestCondition
{
public Set getPatterns()
{
return patterns;
}
private final Set patterns;
private final UrlPathHelper pathHelper;
private final PathMatcher pathMatcher;
private final boolean useSuffixPatternMatch;
private final boolean useTrailingSlashMatch;
private final List fileExtensions;
}

//HandlerMethod
public class HandlerMethod
{
public HandlerMethod(Object bean, Method method)
{
this.bean = bean;
beanFactory = null;
this.method = method;
bridgedMethod = BridgeMethodResolver.findBridgedMethod(method);
parameters = initMethodParameters();
}

public transient HandlerMethod(Object bean, String methodName, Class parameterTypes[])
throws NoSuchMethodException
{
this.bean = bean;
beanFactory = null;
method = bean.getClass().getMethod(methodName, parameterTypes);
bridgedMethod = BridgeMethodResolver.findBridgedMethod(method);
parameters = initMethodParameters();
}

public HandlerMethod(String beanName, BeanFactory beanFactory, Method method)
{
bean = beanName;
this.beanFactory = beanFactory;
this.method = method;
bridgedMethod = BridgeMethodResolver.findBridgedMethod(method);
parameters = initMethodParameters();
}

protected HandlerMethod(HandlerMethod handlerMethod)
{
bean = handlerMethod.bean;
beanFactory = handlerMethod.beanFactory;
method = handlerMethod.method;
bridgedMethod = handlerMethod.bridgedMethod;
parameters = handlerMethod.parameters;
}

private HandlerMethod(HandlerMethod handlerMethod, Object handler)
{
bean = handler;
beanFactory = handlerMethod.beanFactory;
method = handlerMethod.method;
bridgedMethod = handlerMethod.bridgedMethod;
parameters = handlerMethod.parameters;
}
private final Object bean;
private final BeanFactory beanFactory;
private final Method method;
private final Method bridgedMethod;
private final MethodParameter parameters[];
}

总结:
[color=blue]从以上分析,可以看出RequestMappingHandlerMapping,主要做的工作是将Contoller的带RequestMapping方法,添加到处理方法映射器和路径方法解决器中。[/color]
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值