zoukankan      html  css  js  c++  java
  • ContextLoaderListener与RequestContextListener配置问题

    转自:https://blog.csdn.net/yyqhwr/article/details/83381447

    SSH2、SSM等web应用开发框架的配置过程中,因为都要用到spring,所以,往往我们首先都要配置Spring。Spring配置过程中要考虑两个监听器:

    ContextLoaderListener与RequestContextListener。这两个监听器是什么意思?是不是两个监听器都需要配置?它们之间到底存在什么关系?下面,根据实验和网上的资料解释,我将汇总如下:

    ContextLoaderListener与RequestContextListener

    ContextLoaderListener

    ContextLoaderListener extends ContextLoader implements ServletContextListener。

    ServletContextListener extends EventListener。
    ServletContextListener只负责监听Web容器的启动和关闭的事件。

    ContextLoaderListener(或ContextLoaderServlet)将Web容器与spring容器进行整合。

    这是使用Spring 必须配置 的:

      <listener>
        <listener-class>org.springframework.web.context.ContextLoaderListener</listener-class>
      </listener> 
    • 1
    • 2
    • 3

    Spring配置文件的声明:

    <context-param>
      <param-name>contextConfigLocation</param-name>
      <param-value>classpath:applicationContext.xml</param-value>
    </context-param>

    如果没有显式声明,则 系统默认 在WEB-INF/applicationContext.xml。

    在一个团队使用Spring的实际项目中,应该需要多个Spring的配置文件,如何使用和交叉引用的问题:
    如果想装入多个配置文件,可以用逗号作分隔符,如:

    <context-param>
      <param-name>contextConfigLocation</param-name>
      <param-value>applicationContext-database.xml,applicationContext.xml</param-value>
    </context-param>
    • 1
    • 2
    • 3

    多个配置文件里的交叉引用可以用ref的external或bean解决,例如:

    applicationContext.xml

    <bean id="userService" class="domain.user.service.impl.UserServiceImpl"> 
        <property name="dbbean">
             <ref bean="dbBean"/>
        </property> 
    </bean>
    • 1
    • 2
    • 3
    • 4

    dbBean在applicationContext-database.xml中。

    RequestContextListener

    RequestContextListener implements ServletRequestListener

    ServletRequestListener extends EventListener
    ServletRequestListener监听HTTP请求事件,Web服务器接收的每次请求都会通知该监听器。

    RequestContextListener将Spring容器与Web容器结合的更加密切。这是可选配置,并且后者与scope=”request”搭配使用:

    <listener>
      <listener-class>org.springframework.web.context.request.RequestContextListener</listener-class>
    </listener>
    • 1
    • 2
    • 3

    两者区别

    ContextLoaderListener(或ContextLoaderServlet)将Web容器与spring容器整合。RequestContextListener将Spring容器与Web容器结合的更加密切。
    前者为必选配置,后者为可选配置,并且后者与scope=”request”搭配使用。

    详细案例解析

    spring IOC容器实例化Bean的方式有:

    singleton 在spring IOC容器中仅存在一个Bean实例,Bean以单实例的方式存在.

    prototype 每次从容器中调用Bean时,都返回一个新的实例,即每次调用getBean()时,相当于执行new XxxBean()的操作.

    request 每次HTTP请求都会创建一个新的Bean,该作用域仅适用于webApplicationContext环境.

    session 同一个HTTP session共享一个Bean,不同HTTP session使用不同的Bean,该作用域仅适用于webApplicationContext环境。

    globalSession同一个全局session共享一个Bean,一般用于portlet应用环境,该作用域仅适用于webApplicationContext环境。

    在低版本的spring中,由于只有两个Bean作用域,所以采用singleton=”true|false”的配置方式,spring2.0为了向后兼容,依旧支持这种配置方式.不过,spring2.0推荐采用新的配置方式:scope=”<作用域类型>;”。

    • singleton作用域
      spring以容器的方式提供天然的单实例模式功能,任何POJO无须编写特殊的代码仅通过配置就可以了.

    注意:spring将Bean的默认作用域定为singleton.

    singleton例:

    <bean id="car" class="com.baobaotao.scope.Car" scope="singleton"/>
    
    <bean id="boss1" class="com.baobaotao.scope.Boss">
        <property name="car" ref="car"/>
    </bean>
    • 1
    • 2
    • 3
    • 4

    Car Bean声明为singleton(因为默认是singleton,所以可以不显式指定).

    在默认情况下,spring的ApplicationContext容器在启动时,自动实例化所有singleton的Bean并缓存于容器中。虽然启动时会花费一些时间,但带来两个好处:首先对Bean提前的实例化操作会及早发现一些潜在的配置问题。其次Bean以缓存的方式保存,当运行时使用到该Bean时就无须再实例化了,加快了运行效率.如果用户不希望在容器启动时提前实例化singleton的Bean,可以通过lazy-init属性进行控制:

    <bean id="boos1" class="com.baobaotao.scope.Boss" lazy-init="true">
        <property name="car" ref="car"/>
    </bean>
    • 1
    • 2

    lazy-init=”true”的Bean在某些情况下依旧会提前实例化:如果该Bean被其它需要提前实例化的Bean引用到,spring也将忽略延迟实例化的设置。

    • prototype作用域

    采用scope=”prototype”指定非单实例作用域Bean,请看:

    <bean id="car" class="com.baobaotao.scope.Car" scope="prototype"/>
    
    <bean id="boss1" class="com.baobaotao.scope.Boss">
        <property name="car" ref="car"/>
    </bean>
    
    <bean id="boss2" class="com.baobaotao.scope.Boss">
        <property name="car" ref="car"/>
    </bean>
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9

    boss1,boss2所引用的都是一个独立的Car实例.

    在默认情况下,spring容器在启动时不实例化prototype的Bean。此外,spring容器将prototype的Bean交给调用者后,就不再管理它的生命周期。

    • web应用环境相关的Bean作用域

    如果用户使用spring的webApplicationContext,则可以使用另外3种Bean的作用域:request,session和globalSession。不过,在使用这些作用域之前,首先必须在web容器中进行一些额外的配置,在高版本的web容器中,则可以利用HTTP请求监听器进行配置:

    <web-app>
    ...
    <listener>
        <listener-class>
            org.springframework.web.context.request.RequestContextListener
        </listener-class>
    </listener>
    ...
    </web-app>
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9

    细心的朋友可能有一个疑问:在介绍webApplicationContext初始化时,我们已经通过ContextLoaderListener将web容器与Spring容器整合,为什么这里又要引入一个额外的RequestContextListener以支持Bean的另外3个作用域呢?

    这就是我们需要重点解释的:

    在整合spring容器时使用ContextLoaderListener,它实现了ServletContextListener监听器接口,ServletContextListener只负责监听web容器启动和关闭的事件。

    而RequestContextListener实现ServletRequestListener监听器接口,该监听器监听HTTP请求事件,web服务器接收的每一次请求都会通知该监听器。

    spring容器启动和关闭操作由web容器的启动和关闭事件触发,但如果spring容器中的Bean需要request,session,globalsession作用域的支持,spring容器本身就必须获得web容器的HTTP请求事件,以HTTP请求的事件”驱动”Bean作用域的控制逻辑。

    request作用域

    顾名思义,request作用域的Bean对应一个HTTP请求和生命周期,考虑下面的配置:

    <bean name="car" class="com.baobaotao.scope.Car" scope="request"/>
    • 1

    这样,每次HTTP请求调用到car Bean时,spring容器创建一个新的Car Bean,请求处理完毕后,销毁这个Bean。

    session作用域

    假设将以上car的作用域调整为session类型:

    <bean name="car" class="com.baobaotao.scope.Car" scope="session"/>
    • 1

    这样配置后,car Bean的作用域横跨整个HTTP session,session中所有HTTP请求都共享同一个Car Bean,当HTTP Session结束后,实例才被销毁.

    globalSession作用域

    下面的配置片断将car的作用域设置为了globalSession:

    <bean name="loginController" class="com.baobaotao.scope.Car" scope="globalSession"/>
    • 1

    globalSession作用域类似于session作用域,不过仅在portlet的web应用中使用。Portlet规范定义了全局Session概念,它被组成portlet web应用的所有子portlet共享。如果不在Portlet web应用环境下,globalSession自然等价于session作有域了。

  • 相关阅读:
    . Embedding Python in Another Application¶
    hive wiki
    PC机与ARM板的聊天软件
    Hadoop hive 运行examples例子 andy030611的日志 网易博客
    Notes on Ubuntu (Linux) computing
    数据结构利器之私房STL(上)
    Embedding Python in C/C++: Part I CodeProject
    linux下dup2的实现
    单台服务器上安装Hadoop和Hive十五分钟教程
    Data Structures with C++ Using STL Chapter 3算法概述笔记
  • 原文地址:https://www.cnblogs.com/sharpest/p/7476670.html
Copyright © 2011-2022 走看看