基于springmvc的web应用初始化流程和配置加载注意点

基于springmvc的web应用在初始化时做了什么?application context何时加载?有几种加载方式?

 

和所有的java web框架一样,springmvc实际上就是在典型的servlet处理request的流程上再包裹了一层而已。springmvc的初始化流程也同样和容器初始化servlet流程一样。容器初始化servlet上下文的流程如下,servlet context一般而言就是那个web.xml里设定上下文环境。

 

springmvc中最典型的ServletContextListener实现就是ContextLoaderListener,其重写的contextInitialized方法
定义了spring在初始化servletContext时的一些动作。
其会加载由context-param参数contextConfigLocation中指定的spring application context配置文件。
配置如下:

<context-param>
        <param-name>contextConfigLocation</param-name>
        <param-value>
            /WEB-INF/applicationContext.xml /WEB-INF/applicationContext2.xml
        </param-value>
    </context-param>

 

使用 contextConfigLocation 加载指定路径的配置文件时,多个配置文件可以用逗号,冒号,空格, \t,\n
中任一个来分隔。

如果没有指定contextConfigLocation 参数,ContextLoaderListener会默认加载/WEB-INF/applicationContext.xml这个配置文件。

springmvc将由ContextLoaderListener 载入的application context 叫做 “root application context”
,以区别于servlet的application context。

ServletContextListener在servlet context里的配置参考如下:

<listener>
        <listener-class>org.springframework.web.context.ContextLoaderListener</listener-class>
    </listener>

 

如果没有在servlet context里配置,就不存在”root application context”。

springmvc可以配置多个servlet,每一个 servlet都拥有各自的application context,相互之间不能相互访问。但是”root application context”却是对所有servlet都是可见的。

如果servlet直接使用DispatcherServlet,其application context在DispatcherServlet的init
方法被调用时初始化。
servlet application context的加载策略类似于root application context,首先会查找是否配置了servlet的init-param “contextConfigLocation”,如果有,就使用 contextConfigLocation 指定的路径加载的配置文件时,多个配置文件可以用逗号,冒号,空格, \t,\n
中任一个来分隔。

如果没有指定”contextConfigLocation”参数,则会在   /WEB-INF/下查找 “servlet-name”+”-servlet.xml”
这样的文件加载。如下配置所示,就是/WEB-INF/springDispatcherServlet-servlet.xml

<servlet>
        <servlet-name>springDispatcherServlet</servlet-name>
        <servlet-class>org.springframework.web.servlet.DispatcherServlet</servlet-class>
        <init-param>
            <param-name>contextConfigLocation</param-name>
            <param-value>
                /WEB-INF/servlet-applicationContext.xml
            </param-value>
        </init-param>
        <load-on-startup>1</load-on-startup>
    </servlet>

    <servlet-mapping>
        <servlet-name>springDispatcherServlet</servlet-name>
        <url-pattern>/mvc/*</url-pattern>
    </servlet-mapping>

 

最后,该servlet application context将root application context设置为parent,然后加载完成。

以后在应用里调用applicationContext或者beanFactory的getBean方法去获取实例的时候,都是先尝试从父级application context获取,获取不到,再到当前application context里获取。

除此之外,我们还可以在某个类里以编程式加载application context,比如使用ClassPathXmlApplicationContext或FileSystemXmlApplicationContext。不过这样加载的application context和root application context和servlet application context 分属于不同的可见范围。

发表评论

电子邮件地址不会被公开。 必填项已用*标注

昵称 *