读书人

Spring MVC组件并集成到DispatcherSer

发布时间: 2012-11-10 10:48:50 作者: rapoo

Spring MVC组件并集成到DispatcherServlet初始化过程
DispatcherServlet究竟如何将上下文中的Spring MVC组件Bean装配到DispatcherServlet实例中呢?通过查看DispatcherServlet的initStrategies()方法体中的代码,一切的真相就大白于天下了:

protected void initStrategies(ApplicationContext context) {
initMultipartResolver(); ①初始化上传文件解析器(直译为多部分请求解析器)
initLocaleResolver(); ②初始化本地化解析器
initThemeResolver(); ③初始化主题解析器
initHandlerMappings(); ④初始化处理器映射器
initHandlerAdapters(); ⑤初始化处理器适配器
initHandlerExceptionResolvers();⑥初始化处理器异常解析器
initRequestToViewNameTranslator();⑦初始化请求到视图名翻译器
initViewResolvers(); ⑧初始化视图解析器
}

initStrategies()方法会在DispatcherServlet对应的WebApplicationContext初始化后自动执行,此时DispatcherServlet上下文中的Bean已经初始化完毕。该方法的工作事先通过一定的发现机制查询上下文中的组件Bean,如果找不到则装配默认的组件实例。

Spring MVC定义了一套默认的组件实现类,也就是说即使不在Spring容器中显式配置组件Bean,也会有一套可用的默认组件出现在DispatcherServlet中。Spring在spring.jar包的org/springframework/web/servlet类路径定义了一个DispatcherServlet.properties配置文件,在其中指定了组件的默认实现类:

①本地化解析器
org.springframework.web.servlet.LocaleResolver=org.springframework.web.servlet.i18n.
AcceptHeaderLocaleResolver

②主题解析器
org.springframework.web.servlet.ThemeResolver=org.springframework.web.servlet.theme.FixedThemeResolver

③处理器映射器
org.springframework.web.servlet.HandlerMapping=org.springframework.web.servlet.
handler.BeanNameUrlHandlerMapping

④处理器适配器(共3个)
org.springframework.web.servlet.HandlerAdapter=org.springframework.web.servlet.mvc.
HttpRequestHandlerAdapter,\
org.springframework.web.servlet.mvc.SimpleControllerHandlerAdapter,\
org.springframework.web.servlet.mvc.throwaway.ThrowawayControllerHandlerAdapter

⑤请求到视图名翻译器
org.springframework.web.servlet.RequestToViewNameTranslator=org.springframework.web.servlet.view.
DefaultRequestToViewNameTranslator

⑥视图解析器
org.springframework.web.servlet.ViewResolver=org.springframework.web.servlet.view.
InternalResourceViewResolver

你也可以在DispatcherServlet上下文配置文件中显式配置组件Bean以覆盖DispatcherServlet.properties文件中定义的默认组件。
有些类型的组件仅需要配置一个(如本地化解析器),而有些类型的组件可以配置多个,它们组成一个List列表(如处理器映射器)。对于后者来说,组件类都实现了Spring的Ordered接口,你可以在配置时通过order属性指定相应的优先级。

DispatcherServlet优先采用order值小的组件进行操作,如果它无法完成任务才交由次优先级的组件,以此类推。如果同类组件有些设定了order值,有些没有设定,则没有设定order的组件优先级最低,实际上它被设置为Integer.MAX_VALUE。

DispatcherServlet如何在上下文中查找组件Bean并将它们组装到DispatcherServlet实例中呢?这是一个很值得研究的问题。总的来说,DispatcherServlet采用了“约定Bean名”+“匹配组件类型”的机制查找上下文中的组件Bean,如果通过这个发现机制无法找到组件Bean,则转而使用DispatcherServlet.properties文件中定义的默认实现类。对于可以配置多个组件的组件类型,DispatcherServlet允许自动探测父子容器中匹配类型的Bean,并将它们一起装配到DispatcherServlet中。

我们通过表 1说明每种类型组件的装配过程,带(☆)的组件仅有一个,而带(★)的组件可以拥有多个,它们构成一个List:

表 1 装配各型组件的过程



组件类型 发现机制 文件上传解析器(☆) 1)查找名为multipartResolver类型为MultipartResolver的Bean作为该类型组件;2)没有默认的实现类。所以如果你没有在上下文中显式定义这一类型的组件,DispatcherServlet中将不会拥有该类型的组件。 本地化解析器(☆) 1)查找名为localeResolver类型为LocaleResolver的Bean作为该类型组件;2)如果1)找不到,使用默认的实现类(AcceptHeaderLocaleResolver)创建该类型的组件。 主题解析器(☆) 1)查找名为themeResolver类型为LocaleResolver的Bean作为组件;2)如果1)找不到,使用默认的实现类(FixedThemeResolver)。 处理器映射器(★) 1)如果detectAllHandlerMappings属性为true(默认为true),根据类型匹配(HandlerMapping)机制查找上下文及父Spring容器中所有匹配的Bean,将它们作为该类型组件;2)如果detectAllHandlerMappings属性为false,查找名为handlerMapping类型为HandlerMapping的Bean作为该类型组件;3)如果通过以上方式都找不到,使用BeanNameUrlHandlerMapping实现类创建创建该类型的组件。 处理器适配器(★) 1)如果detectAllHandlerAdapters属性为true(默认为true),根据类型匹配(HandlerAdapter)机制查找上下文及父Spring容器中所有匹配的Bean,将它们作为该类型组件;2)如果detectAllHandlerAdapters属性为false,查找名为handlerAdapter类型为HandlerAdapter的Bean作为该类型组件;3)如果通过以上方式都找不到,使用DispatcherServlet.properties配置文件中指定的三个实现类分别创建一个适配器,添加到适配器列表中。 处理器异常解析器(★) 1)如果detectAllHandlerExceptionResolvers属性为true(默认为true),根据类型匹配(HandlerExceptionResolver)机制查找上下文及父Spring容器中所有匹配的Bean作为该类型组件;2)如果detectAllHandlerExceptionResolvers属性为false,查找名为handlerExceptionResolver类型为HandlerExceptionResolver的Bean作为该类型组件;3)如果通过以上方式都找不到,查找DispatcherServlet.properties中定义的默认实现类,不过该文件中没有对应处理器异常解析器的默认实现类(你可以更改属性文件)。 视图名翻译器(☆) 1)查找名为viewNameTranslator类型为RequestToViewNameTranslator的Bean作为该类型组件;2)如果1)找不到,使用默认的实现类(DefaultRequestToViewNameTranslator)创建该类型的组件。 视图解析器(★) 1)如果detectAllViewResolvers属性为true(默认为true),根据类型匹配(ViewResolver)机制查找上下文及父Spring容器中所有匹配的Bean作为该类型组件;2)如果detectAllViewResolvers属性为false,查找名为viewResolver类型为ViewResolver的Bean作为该类型组件;3)如果通过以上方式都找不到,通过DispatcherServlet.properties中定义的默认实现类(InternalResourceViewResolver)创建该类型的组件。  

读书人网 >VC/MFC

热点推荐