1. 固定特殊bean的id
/** 用于文件上传解析 */
public static final String MULTIPART_RESOLVER_BEAN_NAME = "multipartResolver";
/** 用于区域解析 */
public static final String LOCALE_RESOLVER_BEAN_NAME = "localeResolver";
/** 用于主题解析*/
public static final String THEME_RESOLVER_BEAN_NAME = "themeResolver";
/** 处理器映射*/
public static final String HANDLER_MAPPING_BEAN_NAME = "handlerMapping";
/** 处理器适配器 */
public static final String HANDLER_ADAPTER_BEAN_NAME = "handlerAdapter";
/**用于异常解析 */
public static final String HANDLER_EXCEPTION_RESOLVER_BEAN_NAME = "handlerExceptionResolver";
/**获取逻辑视图名称*/
public static final String REQUEST_TO_VIEW_NAME_TRANSLATOR_BEAN_NAME = "viewNameTranslator";
/**用于视图解析 */
public static final String VIEW_RESOLVER_BEAN_NAME = "viewResolver";
/**FLASH属性,用于解决多次提交问题*/
public static final String FLASH_MAP_MANAGER_BEAN_NAME = "flashMapManager";
在DispatchServlet.java里首先定义了上面的常量,为什么定义这些常量?以及这些常量的用途和坑点在哪?
先来说说可能的坑点:例如在springMVC中我要上传文件,那么我就要在配置文件中配置multipartResolver来解析,
<!-- fileUpload Support -->
<bean id="multipartResolver" class="org.springframework.web.multipart.commons.CommonsMultipartResolver">
<property name="defaultEncoding" value="UTF-8"/>
<!--max size: 10M-->
<property name="maxUploadSize" value="10485760"/>
</bean>
这里 bean的ID只能叫multipartResolver,而不能像spring配置普通bean一样随意命名,否则的话,容器就不识别!为什么要固定bean的id啊? 此是陷阱一.(估计很多初学者可能都放过这个错误。)原因是在Spring MVC的核心类DispatcherServlet中, 把这些bean的id固定了(就是上面贴出来的常量). 你必须保证bean的id相同, 才能正常工作.
为什么定义这些常量?
原因是容器初始化九大组件的时候,会去判断用户有没有指定对应的实现类,如果没有指定,那么容器会去分别给它们进行初始化。
2. 如何初始化?
/**
* DispatcherServlet覆写了FrameworkServlet中的onRefresh方法:
*/
@Override
protected void onRefresh(ApplicationContext context) {
initStrategies(context);
}
/**
* initStrategies方法内部会初始化各个策略接口的实现类,这里很重要。
*/
protected void initStrategies(ApplicationContext context) {
initMultipartResolver(context);
initLocaleResolver(context);
initThemeResolver(context);
initHandlerMappings(context);
initHandlerAdapters(context);
initHandlerExceptionResolvers(context);
initRequestToViewNameTranslator(context);
initViewResolvers(context);
initFlashMapManager(context);
}
OnRefresh 是FrameworkServlet类中的提供的模块方法,在其之类DispatchServlet中进行了重写,
主要用于刷新Spring在web功能实现中所必须使用的全局变量。
可以这样来理解:就像你写的Web程序,启动tomcat加载后可以执行了。现在你又对你的代码进行了修正,这个时候在tomcat中并不能
立马运行出修改后代码的效果,这个时候,你是不是需要重新编译,tomcat再启动就OK了。这里的OnRefresh方法类似于tomcat重启,
仅个人观点。
这里再简单来说下源码的设计思想:
一:重写,子类重写父类的方法,父类能实现的直接拿来用,父类实现不了的自己实装。先拼爹,拼不过了,只能靠自己。。。。
二:onRefresh方法里面并没有来写九大组件的具体初始化方法,而是调用了initStrategies()方法,在initStrategies()方面里面再来初始化。
为什么不直接调用?为什么非要通过initStrategies隔了一层调用?这样反而不是更麻烦了吗?这里大家自己思考,毕竟每个人想法不一样。
九大组件具体是如何初始化的?
请看 精讲 DispatchServlet源码解析(二)