JavaEE——spring mvc启动、请求流程

Web容器初始化过程

web.xml文件

<?xml version="1.0" encoding="UTF-8"?>
<web-app xmlns="http://xmlns.jcp.org/xml/ns/javaee"
         xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
         xsi:schemaLocation="http://xmlns.jcp.org/xml/ns/javaee http://xmlns.jcp.org/xml/ns/javaee/web-app_3_1.xsd"
         version="3.1">

    <display-name>Archetype Created Web Application</display-name>
    <!--welcome pages-->
    <welcome-file-list>
        <welcome-file>index.jsp</welcome-file>
    </welcome-file-list>
<!--spring前端控制器定义-->
    <servlet>
        <servlet-name>springMVC</servlet-name>
        <servlet-class>org.springframework.web.servlet.DispatcherServlet</servlet-class>
        <init-param>
            <param-name>contextConfigLocation</param-name>
            <param-value>classpath:app-servlet.xml</param-value>
        </init-param>
        <load-on-startup>1</load-on-startup>
        <async-supported>true</async-supported>
    </servlet>
    <servlet-mapping>
        <servlet-name>springMVC</servlet-name>
        <url-pattern>/</url-pattern>
    </servlet-mapping>
    <context-param>
        <param-name>contextConfigLocation</param-name>
        <param-value>classpath:applicationContext.xml</param-value>
    </context-param>
    <!--Spring容器加载器-->
    <listener>
        <listener-class>org.springframework.web.context.ContextLoaderListener</listener-class>
    </listener>
</web-app>

启动流程

StandardContext
创建ServletContext
ContextLoaderListener初始化
初始化Spring的上下文WebApplicationContext
调用initWebApplicationContext
实例化IoC容器
bean初始化
调用refresh
调用preInstantiateSingletons方法
将WebApplicationContext添加到servletContext
CreateStandWrapper
LoadServlet
反射实例化并init
Created with Raphaël 2.2.0 Start StandardContext 创建ServletContext ContextLoaderListener初始化 初始化Spring的上下文WebApplicationContext 调用initWebApplicationContext方法 实例化IoC容器 调用refresh方法 bean初始化 调用preInstantiateSingletons方法 将WebApplicationContext 添加到servletContext CreateStandWrapper LoadServlet 反射实例化并init
ContextLoaderListener
<context-param>
    <param-name>contextConfigLocation</param-name>
    <param-value>classpath:applicationContext.xml</param-value>
</context-param>
<!--Spring容器加载器-->
<listener>
    <listener-class>org.springframework.web.context.ContextLoaderListener</listener-class>
</listener>
容器初始化

容器的初始化是通过AbstractApplicationContext的refresh()实现的。

public ClassPathXmlApplicationContext(String[] configLocations, boolean refresh, ApplicationContext parent)
            throws BeansException {
    super(parent);
    setConfigLocations(configLocations);
    if (refresh) {
        refresh();
    }
}

refresh方法

@Override
public void refresh() throws BeansException, IllegalStateException {
    //startupShutdownMonitor对象在spring环境刷新和销毁的时候都会用到,确保刷新和销毁不会同时执行
    synchronized (this.startupShutdownMonitor) {
        // 准备工作,例如记录事件,设置标志,检查环境变量等,并有留给子类扩展的位置,用来将属性加入到applicationContext中
        prepareRefresh();

        // 创建beanFactory,这个对象作为applicationContext的成员变量,可以被applicationContext拿来用,
        // 并且解析资源(例如xml文件),取得bean的定义,放在beanFactory中
        ConfigurableListableBeanFactory beanFactory = obtainFreshBeanFactory();

        // 对beanFactory做一些设置,例如类加载器、spel解析器、指定bean的某些类型的成员变量对应某些对象等
        prepareBeanFactory(beanFactory);

        try {
            // 子类扩展用,可以设置bean的后置处理器(bean在实例化之后这些后置处理器会执行)
            postProcessBeanFactory(beanFactory);

            // 执行beanFactory后置处理器(有别于bean后置处理器处理bean实例,beanFactory后置处理器处理bean定义)
            invokeBeanFactoryPostProcessors(beanFactory);

            // 将所有的bean的后置处理器排好序,但不会马上用,bean实例化之后会用到
            registerBeanPostProcessors(beanFactory);

            // 初始化国际化服务
            initMessageSource();

            // 创建事件广播器
            initApplicationEventMulticaster();

            // 空方法,留给子类自己实现的,在实例化bean之前做一些ApplicationContext相关的操作
            onRefresh();

            // 注册一部分特殊的事件监听器,剩下的只是准备好名字,留待bean实例化完成后再注册
            registerListeners();

            // 单例模式的bean的实例化、成员变量注入、初始化等工作都在此完成
            finishBeanFactoryInitialization(beanFactory);

            // applicationContext刷新完成后的处理,例如生命周期监听器的回调,广播通知等
            finishRefresh();
        }

        catch (BeansException ex) {
            logger.warn("Exception encountered during context initialization - cancelling refresh attempt", ex);

            // 刷新失败后的处理,主要是将一些保存环境信息的集合做清理
            destroyBeans();

            // applicationContext是否已经激活的标志,设置为false
            cancelRefresh(ex);

            // Propagate exception to caller.
            throw ex;
        }
    }
}

##请求处理流程

Created with Raphaël 2.2.0 Start 根据url找到servlet 执行filter 执行service doService doDispatch(开始分配请求) getHandler(根据request找handler,找bean的过程) getHandlerInternal lookupHandlerMethod(进行一系列匹配,找到HandlerMethod) getBean(获取bean) getHandlerAdapter(将handler封装成HandlerAdapter) Handle(执行controller的方法) applyPostHandle(将mv写进response)
  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值