SpringMVC的启动流程(一)

之前一直在博客园写博客,但是自己不怎么会调样式,就换到csdn.
博客园地址上面是随便写的自己的近些时间的离职想法,和之前学习的时候一些学习笔记,新手上路各位多多关照;
近段时间离职,面试次次碰壁,多次打击之后,自然也燃起了我从现在开始,每天写博客的斗志。同时现在心中有了进攻大厂的打算了(今天刚刚接到阿里的一面的电话,问了4个问题就挂了<哭晕>)。大概要花个一年左右吧。
好的现在进入正题。
SpringMVC,学习Java的非常清楚吧。至于启动流程对于想进大厂的同学有必要深究以下。
先来看我的一个web项目在这里插入图片描述 现在是项目启动了tomcat然后在HttpServletBean上的init的方法打上了断点;因为springMVC的核心组件就是dispatchcherServlet,既然是servlet 就有生命周期,init,service,destory方法,所以web容器启动之后,在页面上输入,对应的URL:http://localhost:8080/eduOnline/;这个时候开始实例化一个servlet,有的同学会问,不是启动tomcat就直接会实例化一个servlet对象吗,不是的,这个问题我今天也研究了下,发现确实是要输入地址才会实例化对象,这个是以什么时候掉用init方法做为依据的,这里不做过多阐述。顺便这里献上dispacherServlet的族谱图SpringMVC核心组件 FrameworkServlet是它的父类,HttpServletBean是FrameworkServlet的父类。而且它(这里指的是核心组件DispatcherServlet)的爸爸和爷爷。代码里可以看到它自己本身没有init方法,它的爷爷有init方法,接下来看代码的跑动所做的事情。
在这里插入图片描述 这里可以看到的是PropertyValues这个类是获取Spring-MVC.xml的配置文件,这个配置是SpringMVC专属的,里面配置了它要扫描的一些包和一些组件
在这里插入图片描述 以上的代码就是找到这个配置文件的目录,走下去
在这里插入图片描述 可以看到是先包装了一下这个bean,这里也有了contextClass,这个对象在springMVC也很重要,主要是他要参与解析xml文件吧,以上的代码就是包装在propertyValue中了
接下来看initServletBean这个方法很重要,主要是用于能够创建webApplicationContext对象。此时已经是在FrameworkServlet中
在这里插入图片描述然后代码到initWebApplicationContext方法中创建一个WebApplicationContext对象
在这里插入图片描述在这里插入图片描述这里是实例化了一个xmlWebApplicationContext对象并把它加载到了webApplicationContext对象中返回。configureAndRefreshWebApplicationContext中refresh方法


    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()));
        ConfigurableEnvironment env = wac.getEnvironment();
        if (env instanceof ConfigurableWebEnvironment) {
            ((ConfigurableWebEnvironment)env).initPropertySources(this.getServletContext(), this.getServletConfig());
        }

        this.postProcessWebApplicationContext(wac);
        this.applyInitializers(wac);
        wac.refresh();
    }
 refresh方法开始获取beanFactory方法
 public void refresh() throws BeansException, IllegalStateException {
        Object var1 = this.startupShutdownMonitor;
        synchronized(this.startupShutdownMonitor) {
            this.prepareRefresh();
            ConfigurableListableBeanFactory beanFactory = this.obtainFreshBeanFactory();
            this.prepareBeanFactory(beanFactory);

            try {
                this.postProcessBeanFactory(beanFactory);
                this.invokeBeanFactoryPostProcessors(beanFactory);
                this.registerBeanPostProcessors(beanFactory);
                this.initMessageSource();
                this.initApplicationEventMulticaster();
                this.onRefresh();
                this.registerListeners();
                this.finishBeanFactoryInitialization(beanFactory);
                this.finishRefresh();
            } catch (BeansException var9) {
                if (this.logger.isWarnEnabled()) {
                    this.logger.warn("Exception encountered during context initialization - cancelling refresh attempt: " + var9);
                }

                this.destroyBeans();
                this.cancelRefresh(var9);
                throw var9;
            } finally {
                this.resetCommonCaches();
            }

        }
    }

两个方法获取

 protected ConfigurableListableBeanFactory obtainFreshBeanFactory() {
        this.refreshBeanFactory();
        ConfigurableListableBeanFactory beanFactory = this.getBeanFactory();
        if (this.logger.isDebugEnabled()) {
            this.logger.debug("Bean factory for " + this.getDisplayName() + ": " + beanFactory);
        }

        return beanFactory;
    }
  protected final void refreshBeanFactory() throws BeansException {
        if (this.hasBeanFactory()) {
            this.destroyBeans();
            this.closeBeanFactory();
        }

        try {
            DefaultListableBeanFactory beanFactory = this.createBeanFactory();
            beanFactory.setSerializationId(this.getId());
            this.customizeBeanFactory(beanFactory);
            this.loadBeanDefinitions(beanFactory);
            Object var2 = this.beanFactoryMonitor;
            synchronized(this.beanFactoryMonitor) {
                this.beanFactory = beanFactory;
            }
        } catch (IOException var5) {
            throw new ApplicationContextException("I/O error parsing bean definition source for " + this.getDisplayName(), var5);
        }
    }

这个方法,这个类
在这里插入图片描述获取bean实例的这里不做叙述,后期有机会在说下;差多获取到webApplicationContext之后,可以完工了,servlet的init方法也启动差不多了,接着就是操作一些组件,像hardleMappings和hadleAdaptor这两个组件找到对应的控制层,将modelandview发信息展示给页面
在这里插入图片描述这个是我的页面<呲牙>

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

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值