Spring web MVC 框架同其它web MVC 框架同樣,是請求驅動的(request driven),圍繞中心Servlet設計的。中心Servlet會分配請求到各個Controllers,以及提供其它功能。Spring的DispatcherServlet就是這種中心Servlet,但作的更多。全部MVC框架都提供定位視圖(address views)的機制,Spring提供view resolvers,讓你可以在瀏覽器上渲染models,而不會把你束縛在某一特定的視圖技術上。有2個接口(Interface)對於Spring處理視圖來講是很重要的,一個是ViewResolver,另外一個是View。 ViewResolver提供視圖名稱與實際視圖的映射關係,View接口定位請求準備和請求處理到視圖技術上。Spring規定,Controller中的全部handler方法,必須解析到一個邏輯視圖,能夠是顯式的(經過返回String、View或ModelView)或者是隱式的(基於協商 based on conventions)。在Spring中,視圖由邏輯視圖名稱定位,而後由一個view resolver解析。java
Spring自身帶有若干種view resolver,好比:AbstractCachingViewResolver、XmlViewResolver、ResourceBundleViewResolver、UrlBasedViewResolver、InternalResourceViewResolver、VelocityViewResolver、FreeMarkerViewResolver
、ContentNegotiatingViewResolver,你能夠使用1種,或鏈式使用多種。使用方法就是在你的*-Servlet.xml配置文件種加入相關的bean。舉例以下:web
<bean id="jspViewResolver" class="org.springframework.web.servlet.view.InternalResourceViewResolver"> <property name="viewClass" value="org.springframework.web.servlet.view.JstlView"/> <property name="prefix" value="/WEB-INF/jsp/"/> <property name="suffix" value=".jsp"/> </bean> <bean id="excelViewResolver" class="org.springframework.web.servlet.view.XmlViewResolver"> <property name="order" value="1"/> <property name="location" value="/WEB-INF/views.xml"/> </bean>
那麼,問題是,Spring是如何從容器中感知到咱們想要使用哪些ViewResoler的呢? 答案就在於DispatcherServlet類中的initViewResolvers方法。spring
DispatcherServlet.java中有一個私有方法,名爲initViewResolvers,代碼片斷以下,就是用來初始化全部ViewResolvers的。瀏覽器
/** * Initialize the ViewResolvers used by this class. * <p>If no ViewResolver beans are defined in the BeanFactory for this * namespace, we default to InternalResourceViewResolver. */ private void initViewResolvers(ApplicationContext context) { 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"); } } }
若是detectAllViewResolvers屬性被設置爲true的話,就會觸發DispatcherServlet從ApplicationContext中加載全部基類爲ViewResolver的Beans,而後存入viewResolvers列表。
(initViewResolvers會被確保在WebApplicationContext被初始化好了之後纔會被調用的)框架