在Spring MVC中,首先进行的是IoC容器的初始化,包括Root和DispatchServlet对应的content。在IoC容器准备好以后,就开始进行MVC的初始化,包括关于HandleMapping、ViewResolver等的初始化。
在Spring MVC中,MVC的初始化在DispatchServlet的initStrategies方法中进行的。
- protected void initStrategies(ApplicationContext context) {
- initMultipartResolver(context);
- initLocaleResolver(context);
- initThemeResolver(context);
-
- initHandlerMappings(context);
- initHandlerAdapters(context);
- initHandlerExceptionResolvers(context);
- initRequestToViewNameTranslator(context);
-
- initViewResolvers(context);
- }
MVC框架需要的主要功能是根据http请求的信息选择合适的controller,调用controller后,根据返回的结果选择合适视图进行渲染。所以在这里主要关注一下这两个方法:initHandlerMappings和initViewResolvers。initHandlerMappings方法初始化了寻找controller的规则,initViewResolvers初始化视图解析的方法。
那么首先来看一下initHandlerMappings。在spring mvc中,关于寻找controller的规则是用HandleMapping表示的,首先看一下HandleMapping接口类图:
在HandlerMapping接口中,定义了getHandler方法,根据http请求,取得对应的处理对象。这个处理请求的对象用HandlerExecutionChain类表示,在这个类中,包含两个主要属性,一个是真正处理请求的handler,另外一个是Interceptor的集合。
介绍完HandlerMapping接口后,就来看一下Spring MVC中是如何初始化HandlerMapping信息的:
- private void initHandlerMappings(ApplicationContext context) {
-
- this.handlerMappings = null;
-
- if (this.detectAllHandlerMappings) {
-
-
- Map<String, HandlerMapping> matchingBeans =
- BeanFactoryUtils.beansOfTypeIncludingAncestors(context, HandlerMapping.class, true, false);
- if (!matchingBeans.isEmpty()) {
- this.handlerMappings = new ArrayList<HandlerMapping>(matchingBeans.values());
-
-
- OrderComparator.sort(this.handlerMappings);
- }
- }
- else {
- try {
- HandlerMapping hm = context.getBean(HANDLER_MAPPING_BEAN_NAME, HandlerMapping.class);
- this.handlerMappings = Collections.singletonList(hm);
- }
- catch (NoSuchBeanDefinitionException ex) {
-
- }
- }
-
-
-
- if (this.handlerMappings == null) {
- this.handlerMappings = getDefaultStrategies(context, HandlerMapping.class);
- if (logger.isDebugEnabled()) {
- logger.debug("No HandlerMappings found in servlet '" + getServletName() + "': using default");
- }
- }
- }
在上述方法中,做的主要工作是是从容器中获取所有HandlerMapping类型的bean,然后将这些bean按照一定的规则进行排序(order接口),最后为handlerMap赋值,这样关于HandlerMapping的信息就全纪录在handlerMap中了。当有http请求时,会遍历handlerMap集合,选择合适的HandlerMapping实现,调用getHandler方法取得HandlerExecutionChain对象,然后执行真正的业务处理。
在调用完controller后,Spring MVC会进行根据执行结果进行视图解析,这个任务是由ViewResolver进行的,关于ViewResolver的工作原理,见这篇文章:http://blog.csdn.net/prince2270/archive/2010/09/17/5891085.aspx。
那下面就来看一下Spring MVC是如何初始化ViewResolver信息的:
- private void initViewResolvers(ApplicationContext context) {
-
- this.viewResolvers = null;
-
- if (this.detectAllViewResolvers) {
-
- Map<String, ViewResolver> matchingBeans =
- BeanFactoryUtils.beansOfTypeIncludingAncestors(context, ViewResolver.class, true, false);
- if (!matchingBeans.isEmpty()) {
- this.viewResolvers = new ArrayList<ViewResolver>(matchingBeans.values());
-
- OrderComparator.sort(this.viewResolvers);
- }
- }
- else {
- try {
- ViewResolver vr = context.getBean(VIEW_RESOLVER_BEAN_NAME, ViewResolver.class);
- this.viewResolvers = Collections.singletonList(vr);
- }
- catch (NoSuchBeanDefinitionException ex) {
-
- }
- }
-
-
-
- if (this.viewResolvers == null) {
- this.viewResolvers = getDefaultStrategies(context, ViewResolver.class);
- if (logger.isDebugEnabled()) {
- logger.debug("No ViewResolvers found in servlet '" + getServletName() + "': using default");
- }
- }
- }
与HandlerMapping信息的初始化方法类似,取得IoC容器中所有的ViewResolver类型的bean,将其放入到viewResolvers中,并按照一定的规则进行排序。
经过MVC的初始化,所有的信息已经准备就绪,时刻准备着处理http请求了