SpringMVC之View设计。

对SpringMVC的view模块来说,他由两个组件支持,分别是RequestToViewNameTranslator和ViewResolver。RequestToViewNameTranslator支持用户自定义对ViewName的解析,如将请求的ViewName加上前缀或者后缀,或者替换成特定的字符串等。而ViewResolver用于根据用户请求的ViewName创建合适的模板引擎来渲染最终的页面,ViewResolver会根据ViewName创建一个View对象,调用View对象的void render(Map model, HttpServletRequest request,HttpServletResponse response)方法渲染页面。

viewNameTranslator的初始化工作比较简单,只是让Spring创建的Bean的对象保存在DispatcherServlet的viewNameTranslator属性。下面看看ViewResolver的初始化过程。

ViewResolver接口有个抽象的实现类AbstractCachingViewResolver,这个类定义一个抽象方法View loadView(String viewName, Locale locale),根据viewName创建View对象。

UrlBasedViewResolver类实现了AbstractCachingViewResolver抽象类,通过设置ViewClass来创建View对象。如果使用FreeMarkerViewResolver类,则会将ViewClass设置为FreeMarkerView.class;如果使用VelocityViewResolver类,则会将ViewClass设置为Velocity View.class。InternalResourceViewResolver类可以通过注入的方式设置ViewClass属性来初始化自定义的View对象。

由于AbstractCachingViewResolver抽象类也继承了WebApplicationObjectSupport,所以所有的AbstractCachingViewResolver子类可以通过覆盖initApplicationContext方法在SpringMVC框架启动时完成初始化工作。如FreeMarkerViewResolver和VelocityViewResolver就是在启动调用setViewClass方法时设置ViewClass属性。

下面看一下SpringMVC解析View的逻辑,如下图所示是渲染JSP页面的时序图。

SpringMVC之View设计。

JSP的ViewResolver对应的是InternalResourceViewResolver类,当调用resolverViewName方法时会调用createView方法,将ViewClass属性对应的InternalViewResolver类实例化。最后调用InternalResourceView的render方法渲染JSP页面。