SpringMVC的初始化
初始化Spring MVC
- 首先到了
GenericServlet#init(ServletConfig)
中,然后调用this#init()
方法,此处的this指向是DispatcherServlet
对象
public void init(ServletConfig config) throws ServletException { this.config = config;
this.init();
}
DispatcherServlet
对象执行init()
方法,DispatcherServlet
对象中的这个方法是继承自HttpServletBean
,此时会进入到HttpServletBean#init
中,这里面的重点是initServletBean()
方法,调用对应的子类进行初始化
public final void init() throws ServletException { // Set bean properties from init parameters.
PropertyValues pvs = new ServletConfigPropertyValues(getServletConfig(), this.requiredProperties);
if (!pvs.isEmpty()) {
try {
BeanWrapper bw = PropertyAccessorFactory.forBeanPropertyAccess(this);
ResourceLoader resourceLoader = new ServletContextResourceLoader(getServletContext());
bw.registerCustomEditor(Resource.class, new ResourceEditor(resourceLoader, getEnvironment()));
initBeanWrapper(bw);
bw.setPropertyValues(pvs, true);
}
//...忽略
}
// Let subclasses do whatever initialization they like. 让子类进行对应的初始化
initServletBean();
}
- 进入到
FrameworkServlet#initServletBean
中,核心是initWebApplicationContext
和initFrameworkServlet
方法
protected final void initServletBean() throws ServletException { getServletContext().log("Initializing Spring " + getClass().getSimpleName() + " "" + getServletName() + """);
try {
//
this.webApplicationContext = initWebApplicationContext();
//
initFrameworkServlet();
}
catch (ServletException | RuntimeException ex) {
logger.error("Context initialization failed", ex);
throw ex;
}
//log..
}
- 首先进入到了
initWebApplicationContext
方法,对web项目上下文进行初始化
protected WebApplicationContext initWebApplicationContext() { //首先获得父容器
WebApplicationContext rootContext =
WebApplicationContextUtils.getWebApplicationContext(getServletContext());
//什么子容器
WebApplicationContext wac = null;
//建立父子容器关系
if (this.webApplicationContext != null) {
// A context instance was injected at construction time -> use it
wac = this.webApplicationContext;
if (wac instanceof ConfigurableWebApplicationContext) {
ConfigurableWebApplicationContext cwac = (ConfigurableWebApplicationContext) wac;
if (!cwac.isActive()) {
// The context has not yet been refreshed -> provide services such as
// setting the parent context, setting the application context id, etc
if (cwac.getParent() == null) {
// The context instance was injected without an explicit parent -> set
// the root application context (if any; may be null) as the parent
cwac.setParent(rootContext);
}
configureAndRefreshWebApplicationContext(cwac);
}
}
}
//查找web容器的引用是否存在, 并创建好空ioc容器
if (wac == null) {
// No context instance was injected at construction time -> see if one
// has been registered in the servlet context. If one exists, it is assumed
// that the parent context (if any) has already been set and that the
// user has performed any initialization such as setting the context id
wac = findWebApplicationContext();
}
//给建好的IOC容器赋值
if (wac == null) {
// No context instance is defined for this servlet -> create a local one
wac = createWebApplicationContext(rootContext);
}
//触发刷新方法
if (!this.refreshEventReceived) {
// Either the context is not a ConfigurableApplicationContext with refresh
// support or the context injected at construction time had already been
// refreshed -> trigger initial onRefresh manually here.
synchronized (this.onRefreshMonitor) {
onRefresh(wac);
}
}
if (this.publishContext) {
// Publish the context as a servlet context attribute.
String attrName = getServletContextAttributeName();
getServletContext().setAttribute(attrName, wac);
}
return wac;
}
- IOC容器初始化以后,调用了
DispatcherServlet
的onRefresh
,在onRefresh
中又调用了initStrategies
方法,初始化SpringMVC的九大组件
@Overrideprotected void onRefresh(ApplicationContext context) {
initStrategies(context);
}
/**
* Initialize the strategy objects that this servlet uses.
* <p>May be overridden in subclasses in order to initialize further strategy objects.
*/
protected void initStrategies(ApplicationContext context) {
//多文件上传组件
initMultipartResolver(context);
//本地语言环境
initLocaleResolver(context);
//模板处理器
initThemeResolver(context);
//HandlerMapping
initHandlerMappings(context);
//适配器
initHandlerAdapters(context);
//异常拦截器
initHandlerExceptionResolvers(context);
//视图预处理器
initRequestToViewNameTranslator(context);
//视图转换器
initViewResolvers(context);
//FlashMap
initFlashMapManager(context);
}
附录: 九大组件
HandlerMapping
根据request找到相应的处理器。因为Handler(Controller)有两种形式,一种是基于类的Handler,另一种是基于Method的Handler(也就是我们常用的)
HandlerAdapter
调用Handler的适配器。如果把Handler(Controller)当做工具的话,那么HandlerAdapter就相当于干活的工人
HandlerExceptionResolver
对异常的处理
ViewResolver
用来将String类型的视图名和Locale解析为View类型的视图
RequestToViewNameTranslator
有的Handler(Controller)处理完后没有设置返回类型,比如是void方法,这是就需要从request中获取viewName
LocaleResolver
从request中解析出Locale。Locale表示一个区域,比如zh-cn,对不同的区域的用户,显示不同的结果,这就是i18n(SpringMVC中有具体的拦截器LocaleChangeInterceptor)
ThemeResolver
主题解析,这种类似于我们手机更换主题,不同的UI,css等
MultipartResolver
处理上传请求,将普通的request封装成MultipartHttpServletRequest
FlashMapManager
用于管理FlashMap,FlashMap用于在redirect重定向中传递参数
以上是 SpringMVC的初始化 的全部内容, 来源链接: utcz.com/z/512623.html