zoukankan      html  css  js  c++  java
  • BeanFactory到WebApplicationContext的结构 以及bean和spring容器的关系

    BeanFactory: Ioc 容器

    ApplicationContext: Spring容器

    WebApplicationContext需要ServletContext实例,也就是说它必须在拥有Web 容器的

    前提下才能完成启动的工作。

    Spring分别提供了用于启动WebApplicationContext的 Servlet和 Web容器监听器: org.springframework.web.context.ContextLoaderServlet;

    org.springframework.web.context.ContextLoaderListener。

    两者的内部都实现了启动 WebApplicationContext 实例的逻辑,我们只要根据 Web 容

    器的具体情况选择两者之一,并在web.xml中完成配置就可以了。

    1. 使用 ContextLoader Listener

    <!确定配置文件的位置--〉
    <context-param>
    <param-name>contextConfigLocation</param-name>

    <!--此处可以列出多个Spring 的 XML 配置文件→
    <param-value>/WEB-INF/daoContext.xml/WEB-iNF/applicationContext.xml</param-value>
    </context-param>
    <!-- 应用启动时,自动加载listener,该 listener会读取上面确定的XML配置文件。
    然后创建ApplicationContext实例--〉
    <listener>
    <listener-class>org.springframework.web.context.ContextLoaderListener</listener-class>
    </listener>

    ContextLoaderListener 通过 Web 容器上下文参数 contextConfigLocation 获取 Spring 配

    置文件的位置。用户可以指定多个配置文件,用逗号、空格或冒号分隔均可。对于未带资

    源类型前缀的配置文件路径, WebApplicationContext默认这些路径相对于Web的部署根路

    径。当然,我们可以采用带资源类型前缀的路径配置,如classpath:spring/*.xml,classpath:spring/*/*.xml,

    和上面的配置是等效的。

    2. 使用 ContextLoaderServlet

    <servlet>
    <!--确定Servlet 的名-->
    <servlet-name>context</servlet-name><!--确定 Servlet对应的类--〉
    <servlet-class>org.springframework.web.context.ContextLoaderServlet</servlet-class>
    <!--确定Servlet的启动级别--〉
    <load-on-startup>l</load-on-startup></servlet>

     采用这种方式时,应将context 的启动级别设成最小,即最优先启动。因为ApplicationContext是整个应用的核心。

    注意:在两种启动方式中,推荐采用第一种。因为根据Servlet2.4规范, listener比Servlet优先启动;关键问题是有些容器并不支持Serlet2.4规范,即不支持listener。支持 listener的容器有:

    ApacheTomcat4.x 及更高版本。

    Jetty4.x及更高版本。

    Resin 2.1.8 及更高版本。

    Orion2.0.2及更高版本。

    BEAWebLogic8.1 SP3

    不支持 listener 的容器有:

    BEAWebLogicupto 8.1 SP2 及更低版本。

    IBMWebSphere 5.x 及更低版本。

    OracleOC4J9.0.3 及更低版本。

    使用Spring容器以后,程序各元素之间的关系图:

     

    Bean配置信息:定义了Bean的实现和依赖关系。

    Spring容器根据 Bean配置信息在容器内部建立Bean注册表。

    3.使用ContextLoaderPlugIn

    上面我们介绍了WebApplicationContext在Servlet容器中初始化的原理,一般的Web应用就可以轻松的使用了,但是,随着Struts的广泛应用,把Struts和Spring整个起来,是一个需要面对的问题,Spring本身也提供了Struts的相关类,主要使用的有org.springframework.web.struts.ActionSupport,我们只要把自己的Action继承自ActionSupport,就是可以调用ActionSupport中getWebApplicationContext()的方法取出WebApplicationContext,但这样一来在Action中,需要取得业务逻辑的地方都要getBean,看上去不够简洁,所以Spring又提供了另一个方法,用org.springframework.web.struts.ContextLoaderPlugIn,这是一个Struts的Plug,在Struts启动时加载,对于Action,可以像管理Bean一样来管理,在struts-config.xml中Action的配置变成类似下面的样子
    <action attribute="aForm" name="aForm" path="/aAction" scope="request"  type="org.springframework.web.struts.DelegatingActionProxy">
      <forward name="forward" path="forward.jsp" />
    </action>
    注意type变成了org.springframework.web.struts.DelegatingActionProxy,之后我们需要建立action-servlet.xml这样的文件,action-servlet.xml符合Spring的spring-beans.dtd标准,在里面定义类似下面的
    <bean name="/aAction" class="com.web.action.Aaction" singleton="false">
      <property name="businessService">
        <ref bean="businessService"/>
      </property>
    </bean>

    com.web.action.Aaction是Action的实现类,businessService是需要的业务逻辑,Spring会把businessService注入到Action中,在Action中只要写businessService的get和set方法就可以了,还有一点,action的bean是singleton="false",即每次新建一个实例,这也解决了Struts中Action的线程同步问题,具体过程是当用户做“/aAction”的HTTP请求(当然应该是“/aAction.do”),Struts会找到这个Action的对应类org.springframework.web.struts.DelegatingActionProxy,DelegatingActionProxy是个代理类,它会去找action-servlet.xml文件中“/aAction”对应的真正实现类,然后把它实例化,同时把需要的业务对象注入,然后执行Action的execute方法。

    使用了ContextLoaderPlugIn,在struts-config.xml中变成类似这样配置
    <plug-in className="org.springframework.web.struts.ContextLoaderPlugIn">
      <set-property property="contextConfigLocation" value="/WEB-INF/applicationContext.xml,/WEB-INF/action-servlet.xml" />
    </plug-in>
    而在web.xml中不再需要ContextLoaderListener或是ContextLoaderServlet。

    说到这里不知道大家会不会有这样的问题,如果使用ContextLoaderPlugIn,如果我们有些程序是脱离Struts的Action环境,我们怎么处理,比如我们要自定义标记库,在标记库中,我们需要调用Spring管理的业务层逻辑对象,这时候我们就很麻烦,因为只有在action中动态注入业务逻辑,其他我们似乎不能取得Spring的WebApplicationContext。

    别急,我们还是来看一下ContextLoaderPlugIn的源码(源码不再贴出),我们可以发现,原来ContextLoaderPlugIn仍然是把WebApplicationContext放在ServletContext中,只是这个KEY不太一样了,这个KEY值为ContextLoaderPlugIn.SERVLET_CONTEXT_PREFIX+ModuleConfig.getPrefix()(具体请查看源代码),这下好了,我们知道了WebApplicationContext放在哪里,只要我们在Web应用中能够取到ServletContext也就能取到WebApplicationContext了:)

  • 相关阅读:
    Struts2笔记——ONGL表达式语言
    Struts2笔记——自定义拦截器
    Struts2笔记——Action校验器
    Struts2笔记——文件上传
    Struts2笔记——与ServletAPI解耦
    Struts2笔记——通配符和动态方法调用
    Struts2笔记——类型转换
    Struts2笔记——result结果类型
    MongoDB相关资料
    公开数据集
  • 原文地址:https://www.cnblogs.com/wnlja/p/3907537.html
Copyright © 2011-2022 走看看