DispatchServlet流程 - 1

DispatchServlet执行请求之前,需要执行一系列方法,主要用于初始化组件:

HttpServletBean
init()核心代码:

    public final void init() throws ServletException { 

// Set bean properties from init parameters.
                // Servlet初始化参数,如:contextAttribute,contextClass,contextConfigLocation,namespace设置到该组件上
                try {
                        PropertyValues pvs = new ServletConfigPropertyValues(getServletConfig(), this.requiredProperties);
                        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覆盖实现的方法
                // 省略日志输出代码
}

SpringIoC容器启动时,会执行HttpServletBean继承HttpServlet的init()方法,初始化contextAttribute,contextClass,contextConfigLocation,namespace到该组件上,通过BeanWrapper进行设置。并且由子类实现initServletBean()作为扩展点,该方法由FrameworkServlet覆盖。


FrameworkServlet的initServletBean()核心代码:
    protected final void initServletBean() throws ServletException {
                // 省略日志输出代码
                try {
this.webApplicationContext = initWebApplicationContext();    // 初始化Web上下文
initFrameworkServlet();    // 子类覆盖实现的方法
}

// 省略异常判断和日志输出代码     

    }

initWebApplicationContext()的核心代码:
    protected WebApplicationContext initWebApplicationContext() {

                // ContextLoaderListener初始化的上下文, ContextLoaderListener的上下文对整个Spring都有效
WebApplicationContext rootContext = WebApplicationContextUtils.getWebApplicationContext(getServletContext());
                WebApplicationContext wac = null;

if (this.webApplicationContext != null) {
// A context instance was injected at construction time -> use it
                        // 创建Servlet上下文
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);
}
}
}
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();
}
if (wac == null) {
// No context instance is defined for this servlet -> create a local one
                        // 如果还是没有对应的上下文,就自己创建一个继承rootContext的上下文
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.
                        // 刷新上下文,初始化使用策略
onRefresh(wac);    // DispatchServlet覆盖实现
}
if (this.publishContext) {
// Publish the context as a servlet context attribute.
String attrName = getServletContextAttributeName();
getServletContext().setAttribute(attrName, wac);
// 省略日志输出代码

}
                return wac;

        }

初始化SpringMVC上下文时,会首先查找ContextLoaderListener初始化的上下文,并创建继承自ContextLoaderListener上下文的child上下文,调用了onRefresh()方法初始化child上下文。

DispatchServlet的onRefresh()核心代码:
    
protected void onRefresh(ApplicationContext context) {
            initStrategies(context);
    }
    protected void initStrategies(ApplicationContext context) {
initMultipartResolver(context);    // 初始化上传文件解析器
initLocaleResolver(context);    // 初始化国际化解析器
initThemeResolver(context);    // 初始化主题解析器
initHandlerMappings(context);    // 初始化处理器映射器
initHandlerAdapters(context);    // 初始化处理器适配器
initHandlerExceptionResolvers(context);    // 初始化处理器异常解析器
initRequestToViewNameTranslator(context);    // 初始化请求至视图名称的解析器
initViewResolvers(context);    // 初始化视图解析器
initFlashMapManager(context);    // 初始化Flash映射管理器
}
至此,DispatchServlet初始化完毕,整个DispatchServlet初始化过程,主要执行了2件事:
1、初始化Spring Web MVC使用的Web上下文,并且可能指定父容器为(ContextLoaderListener加载了根上下文)。

2、初始化DispatcherServlet使用的策略,如HandlerMapping、HandlerAdapter等。

接下来,探讨DispatchServlet处理请求的流程。https://blog.csdn.net/Super_Me_Jason/article/details/79898731

  • 0
    点赞
  • 2
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值