Spring MVC 的源码分析(1)

4 篇文章 0 订阅

Spring MVC 初始化设计分析

总结: 外部容器通过监听器传给spring mvc初始化,这个初始化我们是以分散重写初始化逻辑进入spring ioc 初始化,然后在返回到Spring MVC自己的上下文九大组件初始化
Spring MVC 底层是设计原理是 前端控制模式



我们拿着总结和上面这张图去看具体实现过程,不然在细节过程,我们很容易就迷糊了,拿到总结让我们有一种一览众山小的视角去俯瞰细节.

1.--------Spring MVC实现了Servlert规范--------
这个是Servlet的相关方法

为什么说Spring MVC是实现了Servlet的方法呢?我们去看一下源码

我们知道DispatchServlet是Spring Mvc的核心控制器,由源码可以看出,它的父类就是 GenericServlet,而GenericServlet的父类也是Servlert,所以说,Spring Mvc是实现了Servlet的规范


2.------Spring MVC初始化的过程--------

容器启动的时候初始化,既然上面说了Spring MVC实现了Servlet规范,那么它肯定也会有相应的 init , service , destroy.
不过区别是在 这三个方法是在不同的类实现的,并不是每个类都重写了这三个方法,每个类都会有自己专注的事情来做.

来,我们看下面这几张图,有以下几张图我们可以分析出父类的GenericServlet的init初始化方法,其实最后是第三张图中HttpServlert子类给重写了

(1)GenericServlet进行初始化(爷爷辈)
(2)HttpServlet 做了service方法(儿子辈)

(3)进行了init初始化的方法重写 (孙子辈)

3.------HttpServletBean的初始化方法细节-------------

(1)init初始化方法


(2)真正的初始化方法 initServletBean方法


(3)构建Spring Mvc自己的上下文环境

//这个方法主要是构建Spring mvc自己的上下文
protected WebApplicationContext initWebApplicationContext() {
    //拿到根上下文环境 spring ioc
    WebApplicationContext rootContext = WebApplicationContextUtils.getWebApplicationContext(this.getServletContext());
    //创建spring mvc自己的上下文,但是没有实例化
    WebApplicationContext wac = null;
    //如果不为空说明已经通过构造方法设置了一个上下文对象
    if(this.webApplicationContext != null) {
        wac = this.webApplicationContext;
        if(wac instanceof ConfigurableWebApplicationContext) {
            //当前的spring mvc的上下文
            ConfigurableWebApplicationContext attrName = (ConfigurableWebApplicationContext)wac;
            //这里判断这个上下文有没有被激活过,Bean关系有没有更新一次
            if(!attrName.isActive()) {
                if(attrName.getParent() == null) {
                    //设置属性
                    attrName.setParent(rootContext);
                }
                //没有激活就重新激活一下 我们在看一下激活的具体实现
                this.configureAndRefreshWebApplicationContext(attrName);
            }
        }
    }

    if(wac == null) {
        wac = this.findWebApplicationContext();
    }

    if(wac == null) {
        wac = this.createWebApplicationContext(rootContext);
    }

    if(!this.refreshEventReceived) {
        //调用这个方法初始化Spring Mvc 的九大组件
        this.onRefresh(wac);
    }

    if(this.publishContext) {
        String attrName1 = this.getServletContextAttributeName();
        this.getServletContext().setAttribute(attrName1, wac);
        if(this.logger.isDebugEnabled()) {
            this.logger.debug("Published WebApplicationContext of servlet \'" + this.getServletName() + "\' as ServletContext attribute with name [" + attrName1 + "]");
        }
    }

    return wac;
}
(4)激活上下文的方法
//这里是激活上下文的方法
protected void configureAndRefreshWebApplicationContext(ConfigurableWebApplicationContext wac) {
    if(ObjectUtils.identityToString(wac).equals(wac.getId())) {
        if(this.contextId != null) {
            wac.setId(this.contextId);
        } else {
            wac.setId(ConfigurableWebApplicationContext.APPLICATION_CONTEXT_ID_PREFIX + ObjectUtils.getDisplayString(this.getServletContext().getContextPath()) + "/" + this.getServletName());
        }
    }
    //设置上下文环境
    wac.setServletContext(this.getServletContext());
    //设置配置信息
    wac.setServletConfig(this.getServletConfig());
    //设置命名空间
    wac.setNamespace(this.getNamespace());

    wac.addApplicationListener(new SourceFilteringListener(wac, new FrameworkServlet.ContextRefreshListener(null)));
    ConfigurableEnvironment env = wac.getEnvironment();
    if(env instanceof ConfigurableWebEnvironment) {
        ((ConfigurableWebEnvironment)env).initPropertySources(this.getServletContext(), this.getServletConfig());
    }

    this.postProcessWebApplicationContext(wac);
    this.applyInitializers(wac);
    //刷下上下文
    wac.refresh();
}

(5)我们再来看初始化的最后一步


至此spring mvc的初始化结束

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

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值