一、运行原理
1、执行DispatcherServlet类onRefresh(ApplicationContext context)方法
protected void onRefresh(ApplicationContext context) {
initStrategies(context);
}
2、执行DispatcherServlet类initStrategies(ApplicationContext context)方法
protected void initStrategies(ApplicationContext context) {
initMultipartResolver(context);
initLocaleResolver(context);
initThemeResolver(context);
initHandlerMappings(context);
initHandlerAdapters(context);
initHandlerExceptionResolvers(context);
initRequestToViewNameTranslator(context);
initViewResolvers(context);//标记
initFlashMapManager(context);
}
3、执行DispatcherServlet类initViewResolvers(ApplicationContext context)方法
private void initViewResolvers(ApplicationContext context) {
this.viewResolvers = null;
if (this.detectAllViewResolvers) {//detectAllViewResolvers是类中的属性,默认为true
// 找到说有当前context及其父类context中的视图解释器
Map<String, ViewResolver> matchingBeans =
BeanFactoryUtils.beansOfTypeIncludingAncestors(context, ViewResolver.class, true, false);
if (!matchingBeans.isEmpty()) {
this.viewResolvers = new ArrayList<ViewResolver>(matchingBeans.values());
// 选中所有的视图解释器.
AnnotationAwareOrderComparator.sort(this.viewResolvers);
}
}
else {//detectAllViewResolvers为false则不主动查找视图解释器
try {
ViewResolver vr = context.getBean(VIEW_RESOLVER_BEAN_NAME, ViewResolver.class);//根据IEW_RESOLVER_BEAN_NAME属性直接获取视图解释器
this.viewResolvers = Collections.singletonList(vr);
}
catch (NoSuchBeanDefinitionException ex) {
// 忽视,在之后添加默认的视图解释器
}
}
//确保我们有至少一个视图解释器
// 一个默认视图解释器,如果没有找到其他视图解释器的话.
if (this.viewResolvers == null) {//若经过之前的代码this.viewResolvers仍为空,则执行下方代码
this.viewResolvers = getDefaultStrategies(context, ViewResolver.class);
if (logger.isDebugEnabled()) {
logger.debug("No ViewResolvers found in servlet '" + getServletName() + "': using default");
}
}
}
二、如何实现自定义视图
Spring配置问价中添加如下配置:
<?xml version="1.0" encoding="UTF-8"?>
<beans xmlns="http://www.springframework.org/schema/beans"
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xmlns:context="http://www.springframework.org/schema/context"
xmlns:p="http://www.springframework.org/schema/p"
xmlns:mvc="http://www.springframework.org/schema/mvc"
xsi:schemaLocation="http://www.springframework.org/schema/mvc http://www.springframework.org/schema/mvc/spring-mvc-4.3.xsd
http://www.springframework.org/schema/beans http://www.springframework.org/schema/beans/spring-beans.xsd
http://www.springframework.org/schema/context http://www.springframework.org/schema/context/spring-context-4.3.xsd">
<context:component-scan base-package="com.jd"></context:component-scan>
<bean class="org.springframework.web.servlet.view.InternalResourceViewResolver" p:prefix="/WEB-INF/view/" p:suffix=".jsp"></bean>
<bean class="org.springframework.web.servlet.view.BeanNameViewResolver" p:order="0"></bean>//添加自定义视图解释器,一定要配置优先级,否则会按声明顺序默认赋予优先级
<mvc:annotation-driven></mvc:annotation-driven>
</beans>
自定义视图类:
import java.util.Map;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
import org.springframework.stereotype.Component;
import org.springframework.web.servlet.View;
@Component
public class ToView implements View{
public String getContentType() {
return "text/html; charset=UTF-8";
}
public void render(Map<String, ?> model, HttpServletRequest request, HttpServletResponse response)
throws Exception {
response.getWriter().print("Hello World!");
}
}
运行结果: