1. 在拿到相应的Handler之后 还会用HandlerAdapter来进行适配
默认的HandlerAdapter有三类:
org.springframework.web.servlet.mvc.HttpRequestHandlerAdapter
org.springframework.web.servlet.mvc.SimpleControllerHandlerAdapter
org.springframework.web.servlet.mvc.annotation.AnnotationMethodHandlerAdapter:仅对它进行分析
2. DispatcherServlet.getHandlerAdapter(Object handler)
protected HandlerAdapter getHandlerAdapter(Object handler) throws ServletException {
for (HandlerAdapter ha : this.handlerAdapters) {
if (logger.isTraceEnabled()) {
logger.trace("Testing handler adapter [" + ha + "]");
}
//找到handler匹配的HandlerAdapter
if (ha.supports(handler)) {
return ha;
}
}
......
}
3. AnnotationMethodHandlerAdapter.getMethodResolver(Object handler)
通过handler获取对应的ServletHandlerMethodResolver
这里是线程安全赋值一次的一种方式
private ServletHandlerMethodResolver getMethodResolver(Object handler) {
Class<?> handlerClass = ClassUtils.getUserClass(handler);
ServletHandlerMethodResolver resolver = this.methodResolverCache.get(handlerClass);
//如果不是null自然可以直接返回了,线程安全的单例也是这么实现的
if (resolver == null) {
//这里是为了保证线程安全
synchronized (this.methodResolverCache) {
resolver = this.methodResolverCache.get(handlerClass);
//仍然需要判断
if (resolver == null) {
resolver = new ServletHandlerMethodResolver(handlerClass);
this.methodResolverCache.put(handlerClass, resolver);
}
}
}
return resolver;
}
4. ServletHandlerMethodResolver初始化
这里会把整个Controller类进行细节的处理抽取出有用的类方法信息
这里使用了匿名内部类,整体实现比较优雅
public void init(final Class<?> handlerType) {
Set<Class<?>> handlerTypes = new LinkedHashSet<Class<?>>();
Class<?> specificHandlerType = null;
if (!Proxy.isProxyClass(handlerType)) {
handlerTypes.add(handlerType);
specificHandlerType = handlerType;
}
handlerTypes.addAll(Arrays.asList(handlerType.getInterfaces()));
for (Class<?> currentHandlerType : handlerTypes) {
final Class<?> targetClass = (specificHandlerType != null ? specificHandlerType : currentHandlerType);
//ReflectionUtils会遍历
ReflectionUtils.doWithMethods(currentHandlerType, new ReflectionUtils.MethodCallback() {
//方法级别的匿名内部类,因此直接使用的外部的handlerMethods/initBinderMethods/modelAttributeMethods必须为final型的
@Override
public void doWith(Method method) {
Method specificMethod = ClassUtils.getMostSpecificMethod(method, targetClass);
Method bridgedMethod = BridgeMethodResolver.findBridgedMethod(specificMethod);
//@RequestMapping 的method
if (isHandlerMethod(specificMethod) &&
(bridgedMethod == specificMethod || !isHandlerMethod(bridgedMethod))) {
handlerMethods.add(specificMethod);
}
//@InitBinder 的method
else if (isInitBinderMethod(specificMethod) &&
(bridgedMethod == specificMethod || !isInitBinderMethod(bridgedMethod))) {
initBinderMethods.add(specificMethod);
}
//@ModelAttribute 的method
else if (isModelAttributeMethod(specificMethod) &&
(bridgedMethod == specificMethod || !isModelAttributeMethod(bridgedMethod))) {
modelAttributeMethods.add(specificMethod);
}
}
}, ReflectionUtils.USER_DECLARED_METHODS);
}
// 类级别的所有 @RequestMapping
this.typeLevelMapping = AnnotationUtils.findAnnotation(handlerType, RequestMapping.class);
SessionAttributes sessionAttributes = AnnotationUtils.findAnnotation(handlerType, SessionAttributes.class);
this.sessionAttributesFound = (sessionAttributes != null);
if (this.sessionAttributesFound) {
this.sessionAttributeNames.addAll(Arrays.asList(sessionAttributes.names()));
this.sessionAttributeTypes.addAll(Arrays.asList(sessionAttributes.types()));
}
}