DispatcherServlet在web.xml中的配置
<context-param>
<!--默认配置文件为/WEB-INF/[servlet名字]-servlet.xml-->
<param-name>contextConfigLocation</param-name>
<param-value>WebApplicationContext的上下文配置</param-value>
</context-param>
<!--在启动Web 容器时,自动装配Spring的配置信息-->
<listener>
<listener-class>org.springframework.web.context.ContextLoaderListener</listener-class>
</listener>
<servlet>
<servlet-name>SpringMVC</servlet-name>
<servlet-class>org.springframework.web.servlet.DispatcherServlet</servlet-class>
<!--此处没有配置contextConfigLocation,默认用WebApplicationContext的上下文配置-->
<init-param>
<param-name>contextConfigLocation</param-name>
<param-value>classpath:/spring/spring-mvc.xml</param-value>
</init-param>
</servlet>
<servlet-mapping>
<servlet-name>SpringMVC</servlet-name>
<url-pattern>请求映射</url-pattern>
</servlet-mapping>
- context-param中contextConfigLocation参数,指定用于加载Bean的配置文件,比如加载除Web层的DAO、Service等
- servlet的init-param中contextConfigLocation参数,指定用于初始化Spring Web MVC框架上下文的配置文件。如果没有配置,默认用context-param中contextConfigLocation参数配置文件
- ContextLoaderListener作用:在启动Web 容器时,自动装配Spring的配置信息。
- ContextLoaderListener初始化的上下文加载的Bean是对于整个应用程序共享的;
- DispatcherServlet初始化的上下文只加载Web相关组件,如Controller、HandlerMapping、HandlerAdapter等等
DispatcherServlet初始化顺序
继承体系:
DispatcherServlet->FrameworkServlet->HttpServletBean->HttpServlet
- 第一步:调用HttpServletBean的init()方法,将始化参数设置到该组件上
public abstract class HttpServletBean extends HttpServlet implements EnvironmentAware{
@Override
public final void init() throws ServletException {
//......
//1、将配置文件中的contextConfigLocation初始化参数等设置到该组件,如设置FrameworkServlet的contextConfigLocation属性
try {
PropertyValues pvs = new ServletConfigPropertyValues(getServletConfig(), this.requiredProperties);
// 扩展阅读BeanWrapper
BeanWrapper bw = PropertyAccessorFactory.forBeanPropertyAccess(this);
ResourceLoader resourceLoader = new ServletContextResourceLoader(getServletContext());
bw.registerCustomEditor(Resource.class, new ResourceEditor(resourceLoader, this.environment));
initBeanWrapper(bw);
bw.setPropertyValues(pvs, true);
}
catch (BeansException ex) {
//…………省略其他代码
}
//2、提供给子类初始化的扩展点,该方法由FrameworkServlet覆盖
initServletBean();
if (logger.isDebugEnabled()) {
logger.debug("Servlet '" + getServletName() + "' configured successfully");
}
}
//…………省略其他代码
private static class ServletConfigPropertyValues extends MutablePropertyValues {
public ServletConfigPropertyValues(ServletConfig config, Set<String> requiredProperties) throws ServletException {
Set<String> missingProps = requiredProperties != null && !requiredProperties.isEmpty() ? new HashSet(requiredProperties) : null;
// 读取servlet的init-param中contextConfigLocation参数
Enumeration en = config.getInitParameterNames();
while(en.hasMoreElements()) {
String property = (String)en.nextElement();
Object value = config.getInitParameter(property);
this.addPropertyValue(new PropertyValue(property, value));
if (missingProps != null) {
missingProps.remove(property);
}
}
}
}
}
扩展阅读BeanWrapper:[blog.csdn.net/u012410733/…]
- 第二步:FrameworkServlet通过initServletBean()进行Web上下文初始化
public abstract class FrameworkServlet extends HttpServletBean {
private String contextConfigLocation;// servlet的init-param中contextConfigLocation参数
@Override
protected final void initServletBean() throws ServletException {
......
try {
//1、初始化Web上下文
this.webApplicationContext = initWebApplicationContext();
//2、提供给子类初始化的扩展点
initFrameworkServlet();
}
......
}
protected WebApplicationContext initWebApplicationContext() {
//ROOT上下文(ContextLoaderListener加载的)
WebApplicationContext rootContext = WebApplicationContextUtils.getWebApplicationContext(getServletContext());
WebApplicationContext wac = null;
if (this.webApplicationContext != null) {
// 1、在创建该Servlet注入的上下文
wac = this.webApplicationContext;
if (wac instanceof ConfigurableWebApplicationContext) {
ConfigurableWebApplicationContext cwac = (ConfigurableWebApplicationContext) wac;
if (!cwac.isActive()) {
if (cwac.getParent() == null) {
cwac.setParent(rootContext);
}
configureAndRefreshWebApplicationContext(cwac);
}
}
}
if (wac == null) {
//2、查找已经绑定的上下文
wac = findWebApplicationContext();
}
if (wac == null) {
//3、如果没有找到相应的上下文,并指定父亲为ContextLoaderListener
wac = createWebApplicationContext(rootContext);
}
if (!this.refreshEventReceived) {
//4、刷新上下文(执行一些初始化)
onRefresh(wac);
}
if (this.publishContext) {
// Publish the context as a servlet context attribute.
String attrName = getServletContextAttributeName();
getServletContext().setAttribute(attrName, wac);
//省略部分代码
}
return wac;
}
}
- 第三步:FrameworkServlet通过onRefresh()方法配置前端控制器
public class DispatcherServlet extends FrameworkServlet {
private static final Properties defaultStrategies;// 默认策略,具体见DispatcherServlet.properties
private MultipartResolver multipartResolver;
private LocaleResolver localeResolver;
private ThemeResolver themeResolver;
private List<HandlerMapping> handlerMappings;
private List<HandlerAdapter> handlerAdapters;
private List<HandlerExceptionResolver> handlerExceptionResolvers;
private RequestToViewNameTranslator viewNameTranslator;
private FlashMapManager flashMapManager;
private List<ViewResolver> viewResolvers;
//实现子类的onRefresh()方法,该方法委托为initStrategies()方法。
@Override
protected void onRefresh(ApplicationContext context) {
initStrategies(context);
}
//初始化默认的Spring Web MVC框架使用的策略(如HandlerMapping)
protected void initStrategies(ApplicationContext context) {
initMultipartResolver(context);//文件上传解析
initLocaleResolver(context);//本地化解析
initThemeResolver(context);//主题解析
initHandlerMappings(context);//请求到处理器的映射
initHandlerAdapters(context);//处理器包装为适配器,从而支持多种类型的处理器
initHandlerExceptionResolvers(context);//处理器异常解析
initRequestToViewNameTranslator(context);//将请求URL映射为逻辑视图名
initViewResolvers(context);//把逻辑视图名解析为具体的View
initFlashMapManager(context);// ???
}
/**
* 文件上传解析器
**/
private void initMultipartResolver(ApplicationContext context){
this.multipartResolver = (MultipartResolver)context.getBean("multipartResolver", MultipartResolver.class);
}
/**
* 本地化解析
**/
private void initLocaleResolver(ApplicationContext context){
this.localeResolver = (LocaleResolver)context.getBean("localeResolver", LocaleResolver.class);
}
/**
* 主题解析
**/
private void initThemeResolver(ApplicationContext context){
this.themeResolver = (LocaleResolver)context.getBean("themeResolver", ThemeResolver.class);
}
/**
* 处理器解析,比如BeanNameUrlHandlerMapping,SimpleUrlHandlerMapping等
**/
private void initHandlerMappings(ApplicationContext context){
this.handlerMappings = null;
if (this.detectAllHandlerMappings) {
// 获取IOC容器中实现了HandlerMapping接口的对象
Map<String, HandlerMapping> matchingBeans = BeanFactoryUtils.beansOfTypeIncludingAncestors(context, HandlerMapping.class, true, false);
if (!matchingBeans.isEmpty()) {
this.handlerMappings = new ArrayList(matchingBeans.values());
AnnotationAwareOrderComparator.sort(this.handlerMappings);
}
} else {
HandlerMapping hm = (HandlerMapping)context.getBean("handlerMapping", HandlerMapping.class);
this.handlerMappings = Collections.singletonList(hm);
}
if (this.handlerMappings == null) {
// 获取默认的处理解析器
this.handlerMappings = this.getDefaultStrategies(context, HandlerMapping.class);
}
}
/**
* 初始化适配器
**/
private void initHandlerAdapters(ApplicationContext context) {
this.handlerAdapters = null;
if (this.detectAllHandlerAdapters) {
// 获取IOC容器中实现了HandlerAdapter接口的对象
Map<String, HandlerAdapter> matchingBeans = BeanFactoryUtils.beansOfTypeIncludingAncestors(context, HandlerAdapter.class, true, false);
if (!matchingBeans.isEmpty()) {
this.handlerAdapters = new ArrayList(matchingBeans.values());
AnnotationAwareOrderComparator.sort(this.handlerAdapters);
}
} else {
HandlerAdapter ha = (HandlerAdapter)context.getBean("handlerAdapter", HandlerAdapter.class);
this.handlerAdapters = Collections.singletonList(ha);
}
if (this.handlerAdapters == null) {
// 获取默认的适配器
this.handlerAdapters = this.getDefaultStrategies(context, HandlerAdapter.class);
}
}
/**
* 初始化异常解析器
**/
private void initHandlerExceptionResolvers(ApplicationContext context) {
this.handlerExceptionResolvers = null;
if (this.detectAllHandlerExceptionResolvers) {
Map<String, HandlerExceptionResolver> matchingBeans = BeanFactoryUtils.beansOfTypeIncludingAncestors(context, HandlerExceptionResolver.class, true, false);
if (!matchingBeans.isEmpty()) {
this.handlerExceptionResolvers = new ArrayList(matchingBeans.values());
AnnotationAwareOrderComparator.sort(this.handlerExceptionResolvers);
}
} else {
HandlerExceptionResolver her = (HandlerExceptionResolver)context.getBean("handlerExceptionResolver", HandlerExceptionResolver.class);
this.handlerExceptionResolvers = Collections.singletonList(her);
}
if (this.handlerExceptionResolvers == null) {
// 获取默认的适配器
this.handlerExceptionResolvers = this.getDefaultStrategies(context, HandlerExceptionResolver.class);
}
}
/**
* 将请求URL映射为逻辑视图名
**/
private void initRequestToViewNameTranslator(ApplicationContext context) {
try {
this.viewNameTranslator = (RequestToViewNameTranslator)context.getBean("viewNameTranslator", RequestToViewNameTranslator.class);
} catch (NoSuchBeanDefinitionException var3) {
this.viewNameTranslator = (RequestToViewNameTranslator)this.getDefaultStrategy(context, RequestToViewNameTranslator.class);
}
}
/**
* 初始化视图解析器
**/
private void initViewResolvers(ApplicationContext context) {
this.viewResolvers = null;
if (this.detectAllViewResolvers) {
// 获取IOC容器中实现了ViewResolver接口的对象
Map<String, ViewResolver> matchingBeans = BeanFactoryUtils.beansOfTypeIncludingAncestors(context, ViewResolver.class, true, false);
if (!matchingBeans.isEmpty()) {
this.viewResolvers = new ArrayList(matchingBeans.values());
AnnotationAwareOrderComparator.sort(this.viewResolvers);
}
} else {
ViewResolver vr = (ViewResolver)context.getBean("viewResolver", ViewResolver.class);
this.viewResolvers = Collections.singletonList(vr);
}
if (this.viewResolvers == null) {
// 获取默认的适配器
this.viewResolvers = this.getDefaultStrategies(context, ViewResolver.class);
}
}
}