博客
关于我
强烈建议你试试无所不能的chatGPT,快点击我
SpringMVC启动过程
阅读量:6695 次
发布时间:2019-06-25

本文共 5156 字,大约阅读时间需要 17 分钟。

1、  对于一个web应用,其部署在web容器中,web容器提供一个其一个全局的上下文环境,这个上下文环境就是ServletContext,它为后面的spring IoC容器提供宿主环境;

2、  web.xml中有配置ContextLoaderListener,也可以自定义一个实现ServletContextListener接口的Listener方法,web.xml中的配置实例如下:

com.manager.init.SystemInitListener
     
org.springframework.web.context.ContextLoaderListener

 

Web容器启动时触发ServletContextEvent事件,被contextLoaderListener监听到,并调用contextInitialized方法:

/**     * Initialize the root web application context.   */   public void contextInitialized(ServletContextEvent event) {           this.contextLoader = createContextLoader();           if (this.contextLoader == null) {                 this.contextLoader = this;           }           this.contextLoader.initWebApplicationContext(event.getServletContext());  }

 

这里调用ContextLoader中的initWebApplicationContext方法初始化WebApplicationContext,WebApplicationContext只是一个接口,默认的实现类是XmlWebApplicationContext。为什么是这个XmlWebApplicationContext?我们到ContextLoader中,看到有这么一段static代码块:

static {           // Load default strategy implementations from properties file.           // This is currently strictly internal and not meant to be customized           // by application developers.           try {                 ClassPathResource resource = new ClassPathResource(DEFAULT_STRATEGIES_PATH, ContextLoader.class);                 defaultStrategies = PropertiesLoaderUtils.loadProperties(resource);           }           catch (IOException ex) {                 throw new IllegalStateException("Could not load 'ContextLoader.properties': " + ex.getMessage());           }      }

 

ContextLoader.properties文件内容如下:

# Default WebApplicationContext implementation class for ContextLoader.# Used as fallback when no explicit context implementation has been specified as context-param.# Not meant to be customized by application developers.

 

 

org.springframework.web.context.WebApplicationContext=org.springframework.web.context.support.XmlWebApplicationContext

这样就能根据属性文件中的定义反射出一个XmlWebApplicationContext上下文,也就是默认实现的WebApplicationContext.

再继续看怎么初始化XmlWebApplicationContext之前,我们需要意识到web.xml文件中有配置spring的Ioc容器,也就是:

contextConfigLocation
/WEB-INF/spring/root-context.xml

 

接着就是进入到ContextLoader类中的initWebApplicationContext方法中,看它是怎么初始化的?

public WebApplicationContext initWebApplicationContext(ServletContext servletContext) {              //省略了很多前面的代码              // Store context in local instance variable, to guarantee that              // it is available on ServletContext shutdown.              if (this.context == null) {                     //初始化root WebApplicationContext, 采用默认的或者是用户指定的                     this.context = createWebApplicationContext(servletContext);              }              if (this.context instanceof ConfigurableWebApplicationContext) {                     ConfigurableWebApplicationContext cwac = (ConfigurableWebApplicationContext) this.context;                     if (!cwac.isActive()) {                            //省略部分代码                            //获取contextConfigLocation指定的xml文件,customize the context                            configureAndRefreshWebApplicationContext(cwac, servletContext);                     }              }              //建立servletContext和WebApplicationContext之间的宿主关系              servletContext.setAttribute(WebApplicationContext.ROOT_WEB_APPLICATION_CONTEXT_ATTRIBUTE, this.context);       }//省略部分代码}

 

3、 初始化web.xml中配置的Servlet,这个servlet可以配置多个,最常见的是DispatcherServlet。web.xml中的配置如下图:

   
appServlet
org.springframework.web.servlet.DispatcherServlet
contextConfigLocation
/WEB-INF/spring/appServlet/appServlet-context.xml
1

这个servlet实际上是一个标准的前端控制器,用以转发、匹配、处理每个servlet请求。DispatcherServlet上下文在初始化的时候会建立自己的IoC上下文,用以持有spring mvc相关的bean。在建立DispatcherServlet自己的IoC上下文时,会利用WebApplicationContext.ROOTWEBAPPLICATIONCONTEXTATTRIBUTE先从ServletContext中获取之前的根上下文(即WebApplicationContext)作为自己上下文的parent上下文。有了这个parent上下文之后,再初始化自己持有的上下文。这个DispatcherServlet初始化自己上下文的工作在其initStrategies方法中可以看到,大概的工作就是初始化处理器映射、视图解析等。

/** * Initialize the strategy objects that this servlet uses. * 

May be overridden in subclasses in order to initialize further strategy objects. */protected void initStrategies(ApplicationContext context) { initMultipartResolver(context); initLocaleResolver(context); initThemeResolver(context); initHandlerMappings(context); initHandlerAdapters(context); initHandlerExceptionResolvers(context); initRequestToViewNameTranslator(context); initViewResolvers(context); initFlashMapManager(context); }

 

这个servlet自己持有的上下文默认实现类也是XmlWebApplicationContext。初始化完毕后,spring以与servlet的名字相关(此处不是简单的以servlet名为Key,而是通过一些转换,具体可自行查看源码)的属性为属性Key,也将其存到ServletContext中,以便后续使用。这样每个servlet就持有自己的上下文,即拥有自己独立的bean空间,同时各个servlet共享相同的bean,即根上下文(第2步中初始化的上下文)定义的那些bean。

 

 

参考资料:

[1]

[2] spring的启动过程

[3] IOC是什么

[4] spring启动过程

转载于:https://www.cnblogs.com/echoht/p/3767656.html

你可能感兴趣的文章
用Eclipse追PostgreSQL源码
查看>>
【原创】第一个iOS应用程序
查看>>
PHP去除BOM头的方法
查看>>
提醒 TickTick v2.8.5.4 最新版
查看>>
怎么在Beyond Compare中插入表格数据
查看>>
JSONP
查看>>
【漏洞预警】OpenSSL 远程拒绝服务漏洞
查看>>
成本管理之(成本控制)
查看>>
Java 反射工具类
查看>>
Java继承关系中,父类方法使用实例变量和调用实例方法的探究
查看>>
csdn账号密码
查看>>
AWS 配置 AutoScaling 实现高可用的弹性计算服务
查看>>
Ubuntu 16.04配置hive mysql db元数据
查看>>
Struts2 中的值栈的理解
查看>>
linux下IPTABLES配置详解
查看>>
使用Spring Mail 模块连接STMP服务器发送邮件
查看>>
Tomcat 下面使用软连接指向真实的上传文件夹
查看>>
批量修改日期,按日期生成文件
查看>>
Git的后悔药——重置 签出 撤消 取消跟踪
查看>>
mysql 5.5.x 解压版 安装
查看>>