Spring MVC 应用上下文

先看上文:Spring MVC ApplicationContext

ServletContext

javaee标准规定了,servlet容器需要在应用项目启动时,给应用项目初始化一个ServletContext作为公共环境容器存放公共信息。ServletContext中的信息都是由容器提供的。

例子

通过自定义contextListener获取web.xml中配置的参数

  1. 容器启动时,找到配置文件中的context-param作为键值对放到ServletContext
  2. 然后找到listener,容器调用它的contextInitialized(ServletContextEvent event)方法,执行其中的操作

例如:在web.xml中配置

1
2
3
4
5
6
7
<context-param>
<param-name>key</param-name>
<param-value>hello</param-value>
</context-param>
<listener>
<listener-class>com.zsr.contextlistener.listener.ContextListenerTest</listener-class>
</listener>

配置好之后,在该类中获取对应的参数信息

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
package com.zsr.contextlistener.listener;
import javax.servlet.ServletContext;
import javax.servlet.ServletContextEvent;
import javax.servlet.ServletContextListener;
public class ContextListenerTest implements ServletContextListener {
public void contextDestroyed(ServletContextEvent event) {
System.out.println("*************destroy ContextListener*************");
}
@SuppressWarnings("unused")
public void contextInitialized(ServletContextEvent event) {
System.out.println("*************init ContextListener*************");
ServletContext servletContext = event.getServletContext();
System.out.println("key:"+servletContext.getInitParameter("key"));
}
}

执行流程

  web.xml<context-param></context-param>标签中声明应用范围内的初始化参数

  1. 启动一个WEB项目的时候,容器(如:Tomcat)会去读它的配置文件web.xml.读两个节点: <listener></listener><context-param></context-param>
  2. 紧接着,容器创建一个ServletContext(上下文)。在该应用内全局共享。
  3. 容器将<context-param></context-param>转化为键值对,并交给ServletContext.
  4. 容器创建<listener></listener>中的类实例,即创建监听.该监听器必须实现自ServletContextListener接口
  5. 在监听中会有contextInitialized(ServletContextEvent event)初始化方法
  6. 得到这个context-param的值之后,你就可以做一些操作了.注意,这个时候你的WEB项目还没有完全启动完成.这个动作会比所有的Servlet都要早.换句话说,这个时候,<context-param>中的键值做的操作,将在你的WEB项目完全启动之前被执行.

web.xml中可以定义两种参数:

  • 全局参数(ServletContext),通过<context-param>声明
1
2
3
4
<context-param>
<param-name>key</param-name>
<param-value>hello</param-value>
</context-param>

参数在servlet里面可以通过getServletContext().getInitParameter("key")得到

  • servlet参数,通过在servlet中声明   

    1
    2
    3
    4
    <init-param>
    <param-name>param1</param-name>
    <param-value>avalible in servlet init()</param-value>
    </init-param>

参数只能在servletinit()方法中通过this.getInitParameter("param1")取得

Spring上下文容器配置

 Spring提供了实现ServletContextListener接口的上下文初始化监听器:org.springframework.web.context.ContextLoaderListener

Spring为我们提供的IOC容器,需要我们指定容器的配置文件,然后由该监听器初始化并创建该容器。要求你指定配置文件的地址及文件名称,一定要使用:contextConfigLocation作为参数名称。

1
2
3
4
5
6
7
<context-param>
<param-name>contextConfigLocation</param-name>
<param-value>classpath:web-context.xml</param-value>
</context-param>
<listener>
<listener-class>org.springframework.web.context.ContextLoaderListener</listener-class>
</listener>

该监听器,默认读取/WEB-INF/下的web-context.xml文件。但是通过context-param指定配置文件路径后,便会去你指定的路径下读取对应的配置文件,并进行初始化。

执行流程

ServletContext是由Servlet容器初始化的,那Spring的ContextLoaderListener又做了什么初始化呢?

  1. servlet容器启动,为应用创建一个“全局上下文环境”:ServletContext
  2. 容器调用web.xml中配置的contextLoaderListener,初始化WebApplicationContext上下文环境(即IOC容器),加载context-param指定的配置文件信息到IOC容器中。WebApplicationContextServletContext中以键值对的形式保存
  3. 容器初始化web.xml中配置的servlet,为其初始化自己的上下文信息servletContext,并加载其设置的配置信息到该上下文中。将WebApplicationContext设置为它的父容器。
  4. 此后的所有servlet的初始化都按照3步中方式创建,初始化自己的上下文环境,将WebApplicationContext设置为自己的父上下文环境。

    img

对于作用范围而言,在DispatcherServlet中可以引用由ContextLoaderListener所创建的ApplicationContext中的内容,而反过来不行。

​ 当Spring在执行ApplicationContextgetBean(BeanName)时,如果在自己context中找不到对应的bean,则会在父ApplicationContext中去找。这也解释了为什么我们可以在DispatcherServlet中获取到由ContextLoaderListener对应的ApplicationContext中的bean

参考

Spring-MVC理解之一:应用上下文webApplicationContext

热评文章