Spring MVC理解之应用上下文

初看Spring MVC,迷惑于上下文,看到一篇总结的很好的博客,在此mark一下。添加了一些个人的理解,以及重新做了一下排版。

一、先说ServletContext

  javaee标准规定了,servlet容器需要在应用项目启动时,给应用项目初始化一个ServletContext作为公共环境容器存放公共信息。ServletContext中的信息都是由容器提供的。
  举例:
通过自定义contextListener获取web.xml中配置的参数
1.容器启动时,找到配置文件中的context-param作为键值对放到ServletContext中。
2.然后找到listener,容器调用它的contextInitialized(ServletContextEvent event)方法,执行其中的操作。
例如:在web.xml中配置

<context-param>
    <param-name>key</param-name>
    <param-value>value123</param-value>
</context-param>
<listener>
    <listener-class>com.brolanda.contextlistener.listener.ContextListenerTest</listener-class>
</listener>

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

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

二、spring上下文容器配置

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

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

<context-param>
    <param-name>contextConfigLocation</param-name>
    <param-value>/WEB-INF/applicationContext.xml,/WEB-INF/action-servlet.xml,/WEB-INF/jason-servlet.xml</param-value>
</context-param>
<listener>
    <listener-class>org.springframework.web.context.ContextLoaderListener</listener-class>
</listener>

该监听器,默认读取/WEB-INF/下的applicationContext.xml文件。但是通过context-param指定配置文件路径后,便会去你指定的路径下读取对应的配置文件,并进行初始化。
(context-param参数的配置用来指定Spring IoC容器读取Bean定义的XML文件的路径。ContextLoaderListener 是与web服务器的生命周期相关联的,负责完成IoC容器在web环境中的启动工作。)

三、spring上下文容器配置后,初始化了什么?

  既然,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设置为自己的父上下文环境。
真绿啊
对于作用范围而言,在DispatcherServlet中可以引用由ContextLoaderListener所创建的ApplicationContext中的内容,而反过来不行。当Spring在执行ApplicationContext的getBean时,如果在自己context中找不到对应的bean,则会在父ApplicationContext中去找。这也解释了为什么我们可以在DispatcherServlet中获取到由ContextLoaderListener对应的ApplicationContext中的bean。

四、spring配置时:context:exclude-filter的使用原因

为什么在applicationContext.xml中排除controller,而spring-mvc.xml中include这个controller。

既然知道了spring的启动流程,那么web容器初始化webApplicationContext时作为公共的上下文环境,只需要将service、dao等的配置信息在这里加载,而servlet自己的上下文环境信息不需要加载。故,在applicationContext.xml中将@Controller注释的组件排除在外,而在dispatcherServlet加载的配置文件中将@Controller注释的组件加载进来,方便dispatcherServlet进行控制和查找。故,配置如下:

applicationContext.mxl中:

<context:component-scan base-package='com.linkage.edumanage'>
    <context:exclude-filter expression='org.springframework.stereotype.Controller' type='annotation' />   
</context:component-scan>

spring-mvc.xml中:

<context:component-scan base-package='com.brolanda.cloud'   use-default-filters='false'>
    <context:include-filter expression='org.springframework.stereotype.Controller' type='annotation' />
</context:component-scan> 

原文链接

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值