1.SpringMVC十大核心对象
接口 | 使用场景 | 实现类 | 参考博客 |
MultipartResolver | 用于解析文件上传 | CommonsMultipartResolver | |
StandardServletMultipartResolver | |||
LocaleResolver | 用于国际化 | CookieLocaleResolver | |
FixedLocaleResolver | |||
AcceptHeaderLocaleResolver | |||
SessionLocaleResolver | |||
ThemeResolver | 用户控制页面主题风格 | FixedThemeResolver | |
SessionThemeResolver | |||
CookieThemeResolver | |||
HandlerMapping | 用于为一个请求找到处理类或者处理方法 | BeanNameUrlHandlerMapping | https://blog.youkuaiyun.com/qq_23536449/article/details/99944430 |
SimpleUrlHandlerMapping | https://blog.youkuaiyun.com/qq_23536449/article/details/99944430 | ||
RequestMappingHandlerMapping | https://blog.youkuaiyun.com/qq_23536449/article/details/99944430 | ||
HandlerAdapter | 适配请求处理对象,调用处理器的方法处理请求 | SimpleMappingExceptionResolver | |
RequestMappingHandlerAdapter | |||
SimpleControllerHandlerAdapter | |||
HandlerExceptionResolver | 异常解析处理器,比如给异常返回状态码、返回json文件、返回到某个错误页面 | ExceptionHandlerExceptionResolver | |
DefaultHandlerExceptionResolver | |||
ResponseStatusExceptionResolver | |||
RequestToViewNameTranslator | 在返回view为空时,它能够根据request请求获得viewName | DefaultRequestToViewNameTranslator | |
ViewResolver | 视图解析器,把逻辑视图名称解析为View对象 | InternalResourceViewResolver | |
UrlBasedViewResolver | |||
BeanNameViewResolver | |||
ViewResolverComposite | |||
XmlViewResolver | |||
FlashMapManager | 重定向请求传参用获取上一个request的参数信息 | SessionFlashMapManager | |
View | 视图展示,比如jsp、html、excel、pdf都是视图 | InternalResourceView | |
JstlView | |||
AbstractPdfView | |||
AbstractXlsView |
2.核心对象的初始化
/**
* 初始化此servlet使用的策略对象。
* <p>可以在子类中重写以初始化其他策略对象。
*/
protected void initStrategies(ApplicationContext context) {
//用于解析文件上传
initMultipartResolver(context);
//用于配置国际化
initLocaleResolver(context);
//用于控制主题页面的风格
initThemeResolver(context);
//用于为一个请求找到处理类或者处理方法
initHandlerMappings(context);
//适配请求处理对象,调用处理器的方法处理请求
initHandlerAdapters(context);
//异常解析处理器,比如给异常返回状态码、返回json文件、返回到某个错误页面
initHandlerExceptionResolvers(context);
//在返回view为空时,它能够根据request请求获得viewName
initRequestToViewNameTranslator(context);
//视图解析器,把逻辑视图名称解析为View对象
initViewResolvers(context);
//重定向请求传参用获取上一个request的参数信息
initFlashMapManager(context);
}
a.初始化MultipartResolver对象
/**
* 初始化此类使用的MultipartResolver
* <p>如果没有在BeanFactory中为此命名空间定义具有给定名称的bean,则不提供Multipart的处理。
*/
private void initMultipartResolver(ApplicationContext context) {
try {
this.multipartResolver = context.getBean(MULTIPART_RESOLVER_BEAN_NAME, MultipartResolver.class);
if (logger.isDebugEnabled()) {
logger.debug("Using MultipartResolver [" + this.multipartResolver + "]");
}
} catch (NoSuchBeanDefinitionException ex) {
// Default is no multipart resolver.
this.multipartResolver = null;
if (logger.isDebugEnabled()) {
logger.debug("Unable to locate MultipartResolver with name '" + MULTIPART_RESOLVER_BEAN_NAME +
"': no multipart request handling provided");
}
}
}
b.初始化LocaleResolver
/**
* 初始化此类使用的LocaleResolver。
* <p>如果在此命名空间的BeanFactory中没有使用给定名称定义bean,则默认为AcceptHeaderLocaleResolver。
*/
private void initLocaleResolver(ApplicationContext context) {
try {
this.localeResolver = context.getBean(LOCALE_RESOLVER_BEAN_NAME, LocaleResolver.class);
if (logger.isDebugEnabled()) {
logger.debug("Using LocaleResolver [" + this.localeResolver + "]");
}
} catch (NoSuchBeanDefinitionException ex) {
// We need to use the default.
// 创建默认的哎嘿嘿
this.localeResolver = getDefaultStrategy(context, LocaleResolver.class);
if (logger.isDebugEnabled()) {
logger.debug("Unable to locate LocaleResolver with name '" + LOCALE_RESOLVER_BEAN_NAME +
"': using default [" + this.localeResolver + "]");
}
}
}
c.初始化ThemeResolver
/**
* 初始化此类使用的ThemeResolver。
* <p>如果在此命名空间的BeanFactory中没有使用给定名称定义bean,则默认为FixedThemeResolver。
*/
private void initThemeResolver(ApplicationContext context) {
try {
this.themeResolver = context.getBean(THEME_RESOLVER_BEAN_NAME, ThemeResolver.class);
if (logger.isDebugEnabled()) {
logger.debug("Using ThemeResolver [" + this.themeResolver + "]");
}
} catch (NoSuchBeanDefinitionException ex) {
// 从
this.themeResolver = getDefaultStrategy(context, ThemeResolver.class);
if (logger.isDebugEnabled()) {
logger.debug("Unable to locate ThemeResolver with name '" + THEME_RESOLVER_BEAN_NAME +
"': using default [" + this.themeResolver + "]");
}
}
}
d.初始化HandlerMappings
/**
* 初始化此类使用的HandlerMappings。
* <p>如果没有在BeanFactory中为此命名空间定义HandlerMapping bean,我们默认为BeanNameUrlHandlerMapping。
*/
private void initHandlerMappings(ApplicationContext context) {
this.handlerMappings = null;
if (this.detectAllHandlerMappings) {
// Find all HandlerMappings in the ApplicationContext, including ancestor contexts.
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.
AnnotationAwareOrderComparator.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");
}
}
}
e.初始化HandlerAdapters
/**
* Initialize the HandlerAdapters used by this class.
* <p>If no HandlerAdapter beans are defined in the BeanFactory for this namespace,
* we default to SimpleControllerHandlerAdapter.
*/
private void initHandlerAdapters(ApplicationContext context) {
this.handlerAdapters = null;
if (this.detectAllHandlerAdapters) {
// Find all HandlerAdapters in the ApplicationContext, including ancestor contexts.
Map<String, HandlerAdapter> matchingBeans =
BeanFactoryUtils.beansOfTypeIncludingAncestors(context, HandlerAdapter.class, true, false);
if (!matchingBeans.isEmpty()) {
this.handlerAdapters = new ArrayList<HandlerAdapter>(matchingBeans.values());
// We keep HandlerAdapters in sorted order.
AnnotationAwareOrderComparator.sort(this.handlerAdapters);
}
} else {
try {
HandlerAdapter ha = context.getBean(HANDLER_ADAPTER_BEAN_NAME, HandlerAdapter.class);
this.handlerAdapters = Collections.singletonList(ha);
} catch (NoSuchBeanDefinitionException ex) {
// Ignore, we'll add a default HandlerAdapter later.
}
}
// Ensure we have at least some HandlerAdapters, by registering
// default HandlerAdapters if no other adapters are found.
if (this.handlerAdapters == null) {
this.handlerAdapters = getDefaultStrategies(context, HandlerAdapter.class);
if (logger.isDebugEnabled()) {
logger.debug("No HandlerAdapters found in servlet '" + getServletName() + "': using default");
}
}
}
f.初始化HandlerExceptionResolvers
/**
* 初始化此类使用的HandlerExceptionResolver。
* <p>如果在此命名空间的BeanFactory中没有使用给定名称定义bean,则默认情况下不会出现异常解析程序。
*/
private void initHandlerExceptionResolvers(ApplicationContext context) {
this.handlerExceptionResolvers = null;
if (this.detectAllHandlerExceptionResolvers) {
// Find all HandlerExceptionResolvers in the ApplicationContext, including ancestor contexts.
Map<String, HandlerExceptionResolver> matchingBeans = BeanFactoryUtils
.beansOfTypeIncludingAncestors(context, HandlerExceptionResolver.class, true, false);
if (!matchingBeans.isEmpty()) {
this.handlerExceptionResolvers = new ArrayList<HandlerExceptionResolver>(matchingBeans.values());
// We keep HandlerExceptionResolvers in sorted order.
AnnotationAwareOrderComparator.sort(this.handlerExceptionResolvers);
}
} else {
try {
HandlerExceptionResolver her =
context.getBean(HANDLER_EXCEPTION_RESOLVER_BEAN_NAME, HandlerExceptionResolver.class);
this.handlerExceptionResolvers = Collections.singletonList(her);
} catch (NoSuchBeanDefinitionException ex) {
// Ignore, no HandlerExceptionResolver is fine too.
}
}
// Ensure we have at least some HandlerExceptionResolvers, by registering
// default HandlerExceptionResolvers if no other resolvers are found.
if (this.handlerExceptionResolvers == null) {
this.handlerExceptionResolvers = getDefaultStrategies(context, HandlerExceptionResolver.class);
if (logger.isDebugEnabled()) {
logger.debug("No HandlerExceptionResolvers found in servlet '" + getServletName() + "': using default");
}
}
}
g.初始化RequestToViewNameTranslator对象
/**
* 初始化此servlet实例使用的RequestToViewNameTranslator。
* <p>如果未配置任何实现,则默认为DefaultRequestToViewNameTranslator。
*/
private void initRequestToViewNameTranslator(ApplicationContext context) {
try {
this.viewNameTranslator =
context.getBean(REQUEST_TO_VIEW_NAME_TRANSLATOR_BEAN_NAME, RequestToViewNameTranslator.class);
if (logger.isDebugEnabled()) {
logger.debug("Using RequestToViewNameTranslator [" + this.viewNameTranslator + "]");
}
} catch (NoSuchBeanDefinitionException ex) {
// We need to use the default.
this.viewNameTranslator = getDefaultStrategy(context, RequestToViewNameTranslator.class);
if (logger.isDebugEnabled()) {
logger.debug("Unable to locate RequestToViewNameTranslator with name '" +
REQUEST_TO_VIEW_NAME_TRANSLATOR_BEAN_NAME + "': using default [" + this.viewNameTranslator +
"]");
}
}
}
h.初始化ViewResolvers
/**
* 初始化此类使用的ViewResolvers。
* <p>如果没有为此命名空间的BeanFactory定义ViewResolver bean,我们默认为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.
AnnotationAwareOrderComparator.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");
}
}
}
i.初始化FlashMapManager对象
/**
* 初始化此servlet实例使用的{@link FlashMapManager}。
* <p>如果没有配置任何实现,那么我们默认为{@code org.springframework.web.servlet.support.SessionFlashMapManager}。
*/
private void initFlashMapManager(ApplicationContext context) {
try {
this.flashMapManager = context.getBean(FLASH_MAP_MANAGER_BEAN_NAME, FlashMapManager.class);
if (logger.isDebugEnabled()) {
logger.debug("Using FlashMapManager [" + this.flashMapManager + "]");
}
} catch (NoSuchBeanDefinitionException ex) {
// We need to use the default.
this.flashMapManager = getDefaultStrategy(context, FlashMapManager.class);
if (logger.isDebugEnabled()) {
logger.debug("Unable to locate FlashMapManager with name '" +
FLASH_MAP_MANAGER_BEAN_NAME + "': using default [" + this.flashMapManager + "]");
}
}
}
3.SpringMVC默认给DispatcherSerlvet的九大对象提供的默认值通过如下方法获取
/**
* 返回给定策略接口的默认策略对象。
* <p>默认实现委托给{@link #getDefaultStrategies},期望列表中有一个对象。
*
* @param context the current WebApplicationContext
* @param strategyInterface the strategy interface
* @return the corresponding strategy object
* @see #getDefaultStrategies
*/
protected <T> T getDefaultStrategy(ApplicationContext context, Class<T> strategyInterface) {
List<T> strategies = getDefaultStrategies(context, strategyInterface);
if (strategies.size() != 1) {
throw new BeanInitializationException(
"DispatcherServlet needs exactly 1 strategy for interface [" + strategyInterface.getName() + "]");
}
return strategies.get(0);
}
protected <T> List<T> getDefaultStrategies(ApplicationContext context, Class<T> strategyInterface) {
//class 名称
String key = strategyInterface.getName();
//从DispatcherServlet.properties配置文件寻找className对应的类
String value = defaultStrategies.getProperty(key);
if (value != null) {
//按逗号切分
String[] classNames = StringUtils.commaDelimitedListToStringArray(value);
List<T> strategies = new ArrayList<T>(classNames.length);
for (String className : classNames) {
try {
//加载Class对象
Class<?> clazz = ClassUtils.forName(className, DispatcherServlet.class.getClassLoader());
//创建对象
Object strategy = createDefaultStrategy(context, clazz);
strategies.add((T) strategy);
} catch (ClassNotFoundException ex) {
throw new BeanInitializationException(
"Could not find DispatcherServlet's default strategy class [" + className +
"] for interface [" + key + "]", ex);
} catch (LinkageError err) {
throw new BeanInitializationException(
"Error loading DispatcherServlet's default strategy class [" + className +
"] for interface [" + key + "]: problem with class file or dependent class", err);
}
}
return strategies;
} else {
return new LinkedList<T>();
}
}
可以看到都是从defaultStrategies中获取的,我们在DispatcherServlet中找到该属性;并且找到该属性的初始化方法
private static final Properties defaultStrategies;
static {
// Load default strategy implementations from properties file.
// This is currently strictly internal and not meant to be customized
// by application developers.
try {
ClassPathResource resource = new ClassPathResource(DEFAULT_STRATEGIES_PATH, DispatcherServlet.class);
defaultStrategies = PropertiesLoaderUtils.loadProperties(resource);
} catch (IOException ex) {
throw new IllegalStateException("Could not load '" + DEFAULT_STRATEGIES_PATH + "': " + ex.getMessage());
}
}
上面方法加载读取DispatcherServlet.properties文件:
# Default implementation classes for DispatcherServlet's strategy interfaces.
# Used as fallback when no matching beans are found in the DispatcherServlet context.
# Not meant to be customized by application developers.
org.springframework.web.servlet.LocaleResolver=org.springframework.web.servlet.i18n.AcceptHeaderLocaleResolver
org.springframework.web.servlet.ThemeResolver=org.springframework.web.servlet.theme.FixedThemeResolver
org.springframework.web.servlet.HandlerMapping=org.springframework.web.servlet.handler.BeanNameUrlHandlerMapping,\
org.springframework.web.servlet.mvc.annotation.DefaultAnnotationHandlerMapping
org.springframework.web.servlet.HandlerAdapter=org.springframework.web.servlet.mvc.HttpRequestHandlerAdapter,\
org.springframework.web.servlet.mvc.SimpleControllerHandlerAdapter,\
org.springframework.web.servlet.mvc.annotation.AnnotationMethodHandlerAdapter
org.springframework.web.servlet.HandlerExceptionResolver=org.springframework.web.servlet.mvc.annotation.AnnotationMethodHandlerExceptionResolver,\
org.springframework.web.servlet.mvc.annotation.ResponseStatusExceptionResolver,\
org.springframework.web.servlet.mvc.support.DefaultHandlerExceptionResolver
org.springframework.web.servlet.RequestToViewNameTranslator=org.springframework.web.servlet.view.DefaultRequestToViewNameTranslator
org.springframework.web.servlet.ViewResolver=org.springframework.web.servlet.view.InternalResourceViewResolver
org.springframework.web.servlet.FlashMapManager=org.springframework.web.servlet.support.SessionFlashMapManager