Spring MVC中的MVC初始化
在Spring MVC中,首先进行的是IoC容器的初始化,包括Root和DispatchServlet对应的content。在IoC容器准备好以后,就开始进行MVC的初始化,包括关于HandleMapping、ViewResolver等的初始化。 在Spring MVC中,MVC的初始化在DispatchServlet的initStrategies方法中进行的。[java]
在Spring MVC中,MVC的初始化在DispatchServlet的initStrategies方法中进行的。
- protected void initStrategies(ApplicationContext context) {
- initMultipartResolver(context);
- initLocaleResolver(context);
- initThemeResolver(context);
- //初始化从http请求到controller映射
- 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) {
- // Find all HandlerMappings in the ApplicationContext, including ancestor contexts.
- //取得IoC容器中所有HandlerMapping类型的Bean
- 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.
- //注意排序
- OrderComparator.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");
- }
- }
- }
在上述方法中,做的主要工作是是从容器中获取所有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) {
- //所有的ViewResolver信息保存在这个属性中
- this.viewResolvers = null;
- if (this.detectAllViewResolvers) {
- // Find all ViewResolvers in the ApplicationContext, including ancestor contexts.
- Map<String, ViewResolver> matchingBeans =
- BeanFactoryUtils.beansOfTypeIncludingAncestors(context, ViewResolver.class, true, false);
- if (!matchingBeans.isEmpty()) {
- this.viewResolvers = new ArrayList<ViewResolver>(matchingBeans.values());
- // We keep ViewResolvers in sorted order.
- OrderComparator.sort(this.viewResolvers);
- }
- }
- else {
- try {
- ViewResolver vr = context.getBean(VIEW_RESOLVER_BEAN_NAME, ViewResolver.class);
- this.viewResolvers = Collections.singletonList(vr);
- }
- catch (NoSuchBeanDefinitionException ex) {
- // Ignore, we'll add a default ViewResolver later.
- }
- }
- // Ensure we have at least one ViewResolver, by registering
- // a default ViewResolver if no other resolvers are found.
- 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请求了
欢迎加我的qq技术群425783133
更多推荐
所有评论(0)