先看上文:Spring MVC ApplicationContext
ServletContext
javaee
标准规定了,servlet
容器需要在应用项目启动时,给应用项目初始化一个ServletContext
作为公共环境容器存放公共信息。ServletContext
中的信息都是由容器提供的。
例子
通过自定义contextListener
获取web.xml
中配置的参数
- 容器启动时,找到配置文件中的
context-param
作为键值对放到ServletContext
中 - 然后找到
listener
,容器调用它的contextInitialized(ServletContextEvent event)
方法,执行其中的操作
例如:在web.xml中配置
|
|
配置好之后,在该类中获取对应的参数信息
|
|
执行流程
web.xml
在<context-param></context-param>
标签中声明应用范围内
的初始化参数
- 启动一个WEB项目的时候,容器(如:
Tomcat
)会去读它的配置文件web.xml
.读两个节点:<listener></listener>
和<context-param></context-param>
- 紧接着,容器创建一个
ServletContext
(上下文)。在该应用内全局共享。 - 容器将
<context-param></context-param>
转化为键值对,并交给ServletContext
. - 容器创建
<listener></listener>
中的类实例,即创建监听.该监听器必须实现自ServletContextListener
接口 - 在监听中会有
contextInitialized(ServletContextEvent event)
初始化方法 - 得到这个
context-param
的值之后,你就可以做一些操作了.注意,这个时候你的WEB项目还没有完全启动完成.这个动作会比所有的Servlet都要早.换句话说,这个时候,对<context-param>
中的键值做的操作,将在你的WEB项目完全启动之前被执行.
web.xml
中可以定义两种参数:
- 全局参数(
ServletContext
),通过<context-param>
声明
|
|
参数在servlet
里面可以通过getServletContext().getInitParameter("key")
得到
servlet
参数,通过在servlet
中声明1234<init-param><param-name>param1</param-name><param-value>avalible in servlet init()</param-value></init-param>
参数只能在servlet
的init()
方法中通过this.getInitParameter("param1")
取得
Spring上下文容器配置
Spring提供了实现ServletContextListener
接口的上下文初始化监听器:org.springframework.web.context.ContextLoaderListener
Spring为我们提供的IOC容器,需要我们指定容器的配置文件,然后由该监听器初始化并创建该容器。要求你指定配置文件的地址及文件名称,一定要使用:contextConfigLocation
作为参数名称。
|
|
该监听器,默认读取/WEB-INF/
下的web-context.xml
文件。但是通过context-param
指定配置文件路径后,便会去你指定的路径下读取对应的配置文件,并进行初始化。
执行流程
ServletContext
是由Servlet
容器初始化的,那Spring的ContextLoaderListener
又做了什么初始化呢?
servlet
容器启动,为应用创建一个“全局上下文环境”:ServletContext
- 容器调用
web.xml
中配置的contextLoaderListener
,初始化WebApplicationContext
上下文环境(即IOC容器),加载context-param
指定的配置文件信息到IOC容器中。WebApplicationContext
在ServletContext
中以键值对的形式保存 - 容器初始化
web.xml
中配置的servlet
,为其初始化自己的上下文信息servletContext
,并加载其设置的配置信息到该上下文中。将WebApplicationContext设置为它的父容器。 此后的所有
servlet
的初始化都按照3步中方式创建,初始化自己的上下文环境,将WebApplicationContext
设置为自己的父上下文环境。
对于作用范围而言,在DispatcherServlet
中可以引用由ContextLoaderListener
所创建的ApplicationContext
中的内容,而反过来不行。
当Spring在执行ApplicationContext
的getBean(BeanName)
时,如果在自己context
中找不到对应的bean,则会在父ApplicationContext
中去找。这也解释了为什么我们可以在DispatcherServlet
中获取到由ContextLoaderListener
对应的ApplicationContext中的bean
。