- spring mvc初始化
- 请求如何从url到controller
- 请求参数绑定
- 请求结果返回
- 视图解析
截图为spring-webmvc-4.2.6.xxxx.jar

简化一下继承关系为:

-
初始化
Servlet在初始化时会调用init()方法,这个init()方法最终会调用到DispatcherServlet的initStrategies()方法,该方法内容如下。
protected void initStrategies(ApplicationContext context) {
initMultipartResolver(context);
initLocaleResolver(context);
initThemeResolver(context);
// 用于初始化请求
initHandlerMappings(context);
initHandlerAdapters(context);
initHandlerExceptionResolvers(context);
initRequestToViewNameTranslator(context);
initViewResolvers(context);
initFlashMapManager(context);
}
最终调到
/**
* Initialize the HandlerMappings used by this class.
* <p>If no HandlerMapping beans are defined in the BeanFactory for this namespace,
* we default to BeanNameUrlHandlerMapping.
*/
private void initHandlerMappings(ApplicationContext context) {
this.handlerMappings = null;
if (this.detectAllHandlerMappings) {
// Find all HandlerMappings in the ApplicationContext, including ancestor contexts.
Map<String, HandlerMapping> matchingBeans =
BeanFactoryUtils.beansOfTypeIncludingAncestors(context, HandlerMapping.class, true, false);
if (!matchingBeans.isEmpty()) {
this.handlerMappings = new ArrayList<HandlerMapping>(matchingBeans.values());
// We keep HandlerMappings in sorted order.
AnnotationAwareOrderComparator.sort(this.handlerMappings);
}
}
else {
try {
HandlerMapping hm = context.getBean(HANDLER_MAPPING_BEAN_NAME, HandlerMapping.class);
this.handlerMappings = Collections.singletonList(hm);
}
catch (NoSuchBeanDefinitionException ex) {
// Ignore, we'll add a default HandlerMapping later.
}
}
// Ensure we have at least one HandlerMapping, by registering
// a default HandlerMapping if no other mappings are found.
if (this.handlerMappings == null) {
this.handlerMappings = getDefaultStrategies(context, HandlerMapping.class);
if (logger.isDebugEnabled()) {
logger.debug("No HandlerMappings found in servlet '" + getServletName() + "': using default");
}
}
}
handlerMappings是一个List<HandlerMapping>,包含的元素有RequestMappingHandlerMapping,BeanNameUrlHandlerMapping,SimpleUrlHandlerMapping等
RequestMappingHandlerMapping的继承关系图如下:

AbstractHandlerMethodMapping.java里有
private final MappingRegistry mappingRegistry = new MappingRegistry();
MappingRegistry的定义
private final Map<T, MappingRegistration<T>> registry = new HashMap<T, MappingRegistration<T>>();
MappingRegistration
private static class MappingRegistration<T> {
private final T mapping; //T为RequestMappingInfo,封装了请求信息,包含请求路径,请求头等
private final HandlerMethod handlerMethod;//请求对应的处理方法
}
由此大概明白了,spring mvc是用MappingRegistration.java来映射请求url和要执行的method之间的关系的
protected void initHandlerMethods() {
if (logger.isDebugEnabled()) {
logger.debug("Looking for request mappings in application context: " + getApplicationContext());
}
// 获取所有的bean name
String[] beanNames = (this.detectHandlerMethodsInAncestorContexts ?
BeanFactoryUtils.beanNamesForTypeIncludingAncestors(getApplicationContext(), Object.class) :
getApplicationContext().getBeanNamesForType(Object.class));
for (String beanName : beanNames) {
if (!beanName.startsWith(SCOPED_TARGET_NAME_PREFIX)) {
Class<?> beanType = null;
try {
beanType = getApplicationContext().getType(beanName);
}
catch (Throwable ex) {
// An unresolvable bean type, probably from a lazy bean - let's ignore it.
if (logger.isDebugEnabled()) {
logger.debug("Could not resolve target class for bean with name '" + beanName + "'", ex);
}
}
// 如果该bean带有@Controller和@RequestMapping注解,则该bean被封装成HandlerMethod注册到mappingRegistry
if (beanType != null && isHandler(beanType)) {
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);
Map<Method, T> methods = MethodIntrospector.selectMethods(userType,
new MethodIntrospector.MetadataLookup<T>() {
@Override
public T inspect(Method method) {
return getMappingForMethod(method, userType);
}
});
if (logger.isDebugEnabled()) {
logger.debug(methods.size() + " request handler methods found on " + userType + ": " + methods);
}
for (Map.Entry<Method, T> entry : methods.entrySet()) {
registerHandlerMethod(handler, entry.getKey(), entry.getValue());
}
}
public void register(T mapping, Object handler, Method method) {
this.readWriteLock.writeLock().lock();
try {
HandlerMethod handlerMethod = createHandlerMethod(handler, method);
assertUniqueMethodMapping(handlerMethod, mapping);
if (logger.isInfoEnabled()) {
logger.info("Mapped \"" + mapping + "\" onto " + handlerMethod);
}
this.mappingLookup.put(mapping, handlerMethod);
List<String> directUrls = getDirectUrls(mapping);
for (String url : directUrls) {
this.urlLookup.add(url, mapping);
}
String name = null;
if (getNamingStrategy() != null) {
name = getNamingStrategy().getName(handlerMethod, mapping);
addMappingName(name, handlerMethod);
}
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));
}
finally {
this.readWriteLock.writeLock().unlock();
}
}
-
请求转发
servlet的doService方法最终调到DispatcherServlet的doDispatch(..),源码简化后为
protected void doDispatch(HttpServletRequest request, HttpServletResponse response) throws Exception {
HttpServletRequest processedRequest = request;
HandlerExecutionChain mappedHandler = null;
try {
// 根据请求来获取相应的HandlerExecutionChain,这个类是响应请求方法的一个封装类
mappedHandler = getHandler(processedRequest);
// 获取请求适配器
HandlerAdapter ha = getHandlerAdapter(mappedHandler.getHandler());
// 调用响应方法
mv = ha.handle(processedRequest, response, mappedHandler.getHandler());
}
catch (Exception ex) {
...
}
}
网友评论