`

Spring中ApplicationContext加载机制

 
阅读更多

转:http://blog.csdn.net/edisondu1983/article/details/3954417  有删改。

 

 

 

Spring中ApplicationContext加载机制。 
          加载器目前有两种选择:ContextLoaderListener和ContextLoaderServlet。 
         这两者在功能上完全等同,只是一个是基于Servlet2.3版本中新引入的Listener接口实现,而另一个基于Servlet接口实现。开发中可根据目标Web容器的实际情况进行选择。

配置非常简单,在web.xml中增加 : 
<listener> 
  <listener-class> 
       org.springframework.web.context.ContextLoaderListener 
  </listener-class> 
</listener> 
或: 
<servlet> 
    <servlet-name>context</servlet-name> 
    <servlet-class> 
       org.springframework.web.context.ContextLoaderServlet 
    </servlet-class> 
    <load-on-startup>1</load-on-startup> 
</servlet> 
  
          通过以上配置,Web容器会自动加载/WEB-INF/applicationContext.xml初始化 
ApplicationContext实例,如果需要指定配置文件位置,可通过context-param加以指定: 
<context-param> 
    <param-name>contextConfigLocation</param-name> 
    <param-value>/WEB-INF/myApplicationContext.xml</param-value> 
</context-param>

        配置完成之后,即可通过 
 WebApplicationContextUtils.getWebApplicationContext方法在Web应用中获取ApplicationContext引用。

如:ApplicationContext ctx=WebApplicationContextUtils.getWebApplicationContext(); 
    LoginAction action=(LoginAction)ctx.getBean("action");

 

=============================

 

Spring中WebApplicationContext的研究 

ApplicationContext是Spring的核心,Context我们通常解释为上下文环境,我想用“容器”来表述它更容易理解一些,ApplicationContext则是“应用的容器”,Spring把Bean放在这个容器中,在需要的时候,用getBean方法取出 ,虽然我没有看过这一部分的源代码,但我想它应该是一个类似Map的结构。 
在Web应用中,我们会用到WebApplicationContext,WebApplicationContext继承自ApplicationContext,先让我们看看在Web应用中,怎么初始化WebApplicationContext,在web.xml中定义: 
<context-param> 
    <param-name>contextConfigLocation</param-name> 
    <param-value>/WEB-INF/applicationContext.xml</param-value> 
</context-param> 

<listener> 
    <listener-class>org.springframework.web.context.ContextLoaderListener</listener-class> 
</listener> 

<!-- OR USE THE CONTEXTLOADERSERVLET INSTEAD OF THE LISTENER 
<servlet> 
    <servlet-name>context</servlet-name> 
    <servlet-class>org.springframework.web.context.ContextLoaderServlet</servlet-class> 
    <!-- 自动启动 -->

<load-on-startup>1</load-on-startup> 
</servlet> 
--> 

可以看出,有两种方法,一个是用ContextLoaderListener这个Listerner,另一个是ContextLoaderServlet这个Servlet,这两个方法都是在web应用启动的时候来初始化WebApplicationContext ,我个人认为Listerner要比Servlet更好一些,因为Listerner监听应用的启动和结束,而Servlet得启动要稍微延迟一些,如果在这时要做一些业务的操作,启动的前后顺序是有影响的。 

那么在ContextLoaderListener和ContextLoaderServlet中到底做了什么呢? 
以ContextLoaderListener为例,我们可以看到 
public void contextInitialized(ServletContextEvent event) { 
  this.contextLoader = createContextLoader(); 
  this.contextLoader.initWebApplicationContext(event.getServletContext()); 

protected ContextLoader createContextLoader() { 
  return new ContextLoader(); 

ContextLoader是一个工具类,用来初始化WebApplicationContext,其主要方法就是initWebApplicationContext,我们继续追踪initWebApplicationContext这个方法(具体代码我不贴出,大家可以看Spring中的源码),我们发现,原来ContextLoader是把WebApplicationContext(XmlWebApplicationContext是默认实现类)放在了ServletContext中ServletContext也是一个“容器”,也是一个类似Map的结构,而WebApplicationContext在ServletContext中的KEY就是WebApplicationContext.ROOT_WEB_APPLICATION_CONTEXT_ATTRIBUTE,我们如果要使用WebApplicationContext则需要从ServletContext取出,Spring提供了一个WebApplicationContextUtils类,可以方便的取出WebApplicationContext,只要把ServletContext传入就可以了。 

上面我们介绍了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了:)

 

--------------------------

加载spring配置文件还是放到src下比较好。
<context-param>
<param-name>contextConfigLocation</param-name>
<param-value>
classpath:applicationContext-hibernate.xml,
classpath:applicationContext-dao.xml,
classpath:applicationContext-service.xml,
classpath:applicationContext-struts.xml
</param-value>
</context-param>

<listener>
<listener-class>
org.springframework.web.context.ContextLoaderListener
</listener-class>
</listener>

--------------------------Sping in Action 7.2.5--------------------------------------

7.2.5Rounding out the Spring application context
As I mentioned earlier, DispatcherServlet loads its Spring application context from
a single XML file whose name is based on its <servlet-name>. But what about the
other beans we’ve declared in previous chapters, such as the SpitterService bean? If
DispatcherServlet is going to load its beans from a file named spitter-servlet.xml,
then won’t we need to declare those other beans in spitter-servlet.xml?
In the earlier chapters we’ve split our Spring configuration across multiple XML
files: one for the service layer, one for the persistence layer, and another for the data
source configuration. Although not strictly required, it’s a good idea to organize our

Spring configuration across multiple files. With that in mind, it makes sense to put all
of the web layer configuration in spitter-servlet.xml, the file loaded by Dispatcher-
Servlet. But we still need a way to load the other configuration files.
That’s where ContextLoaderListener comes into play. ContextLoaderListener is
a servlet listener that loads additional configuration into a Spring application context
alongside the application context created by DispatcherServlet. To use Context-
LoaderListener, add the following <listener> declaration to the web.xml file:
<listener>
       <listener-class>
           org.springframework.web.context.ContextLoaderListener
       </listener-class>
</listener>

We also need to tell ContextLoaderListener which Spring configuration file(s) it
should load. If not specified otherwise, the context loader will look for a Spring con-
figuration file at /WEB-INF/applicationContext.xml. But this single file doesn’t lend
itself to breaking up the application context into several pieces. So we’ll need to over-
ride this default.
To specify one or more Spring configuration files for ContextLoaderListener to
load, set the contextConfigLocation parameter in the servlet context:
<context-param>
     <param-name>contextConfigLocation</param-name>
     <param-value>
             /WEB-INF/spitter-security.xml
            classpath:service-context.xml
            classpath:persistence-context.xml
            classpath:dataSource-context.xml
       </param-value>
</context-param>

The contextConfigLocation parameter is specified as a list of paths. Unless specified
otherwise, the paths are relative to the application root. But since our Spring configuration is split across multiple XML files that are scattered across several JAR files in the
web application, we’ve prefixed some of them with classpath: to load them as
resources from the application classpath and others with a path local to the web
application.
You’ll recognize that we’ve included the Spring configuration files that we created
in previous chapters. You may also notice a few extra configuration files that we’ve not
covered yet. Don’t worry...we’ll get to those in later chapters.
Now we have our first controller written and ready to serve requests for the Spitter
application’s home page. If all we needed is a home page, we’d be done. But there’s
more to Spitter than just the home page, so let’s continue building out the applica-
tion. The next thing we’ll try is to write a controller that can handle input.

 

 

分享到:
评论

相关推荐

    高级开发spring面试题和答案.pdf

    SPI 机制(Java SPI 实际上是“基于接口的编程+策略模式+配置文件”组合实现的动态加载机制), 很多地方有用到: AOP Spring的AOP的底层实现原理; 为什么jdk动态代理是必须是接口 两种动态代理的区别 AOP实现方式:...

    Spring中文帮助文档

    6.8.4. 在Spring应用中使用AspectJ加载时织入(LTW) 6.9. 更多资源 7. Spring AOP APIs 7.1. 简介 7.2. Spring中的切入点API 7.2.1. 概念 7.2.2. 切入点运算 7.2.3. AspectJ切入点表达式 7.2.4. 便利的切入...

    spring boot源码

    2. 创建Spring容器对象ApplicationContext,加载各种配置 3. 在容器创建前,通过监听器机制,应对不同阶段加载数据、更新数据的需求 4. 容器初始化过程中追加各种功能,例如统计时间、输出日志等 监听器类型 1. 在...

    Spring.3.x企业应用开发实战(完整版).part2

    Spring3.0是Spring在积蓄了3年之久后,隆重推出的一个重大升级版本,进一步加强了Spring作为Java领域第一开源平台的翘楚地位。  Spring3.0引入了众多Java开发者翘首以盼的新功能...附录B 在Spring中开发Web Service

    第24次课-1 Spring与Hibernate的整合

    通用的资源管理:Spring的ApplicationContext能够管理SessionFactory,通过配置文件可以方便改写相关的配置。 有效的Session管理:Spring提供了有效、简单、安全的Hibernate Session处理。 IoC容器降低了DAO组件与...

    Spring API

    6.8.4. 在Spring应用中使用AspectJ加载时织入(LTW) 6.9. 更多资源 7. Spring AOP APIs 7.1. 简介 7.2. Spring中的切入点API 7.2.1. 概念 7.2.2. 切入点运算 7.2.3. AspectJ切入点表达式 7.2.4. 便利的切入...

    Spring3.x企业应用开发实战(完整版) part1

    Spring3.0是Spring在积蓄了3年之久后,隆重推出的一个重大升级版本,进一步加强了Spring作为Java领域第一开源平台的翘楚地位。  Spring3.0引入了众多Java开发者翘首以盼的新功能...附录B 在Spring中开发Web Service

    SpringBoot启动过程-mind版.md

    1. **加载配置:** Spring Boot会读取项目中的配置文件(如`application.properties`或`application.yml`),并将其中的配置信息加载到内存中,以供后续使用。 2. **初始化应用上下文:** Spring Boot会创建一个...

    基于SSH模拟当当网项目(电子商务平台)

    采用整合插件注入方式使用Spring容器中的Service或DAO. (默认按名称匹配规则) 4.配置信息的改造 Service和DAO需要交给Spring容器. struts.xml不需要改变,因为引入struts-spring-plugin.jar后,Action创建会交给...

    BOS技术整理-05

    将cxf配置在web.xml中 与applicationContext.xml中声明服务的bean 创建一个maven项目(war) 编写实体类,Service 导入applicationContext.xml 配置cxf的发布 客户端测试代码 WebService-RS ...

    SpringFXExample

    此外,通过在加载程序上设置自定义生成器工厂,可以使用Bean工厂来生成在FXML本身中声明的实例。 (此行为已启用,但未在此应用程序中使用。) 使用诸如Spring之类的依赖项注入框架来管理控制器,可以提供一种简单...

    java面试宝典

    105、spring工作机制及为什么要用? 24 106、HttpSession session = request.getSession() 24 107、getParameter与 getAttribute的区别? 24 108、以下哪一个不是赋值符号? 25 109、以下哪个不是Collection的子接口?...

    千方百计笔试题大全

    105、spring工作机制及为什么要用? 24 106、HttpSession session = request.getSession() 24 107、getParameter与 getAttribute的区别? 24 108、以下哪一个不是赋值符号? 25 109、以下哪个不是Collection的子接口?...

    java微信公众号MVC开发框架

    spring配置文件applicationContext.xml里面需要配置WeixinConfigurer,这是jwx唯一必须配置项,如果没有配置,启动阶段会报错。 &lt;value&gt;com.telecomjs.yc.controller&lt;/value&gt; component-scan配置了...

    J2EE应用开发详解

    246 14.5.2 CORBA和RMI的互操作 247 14.6 小结 248 第15章 Spring框架 249 15.1 Spring 2.0的体系结构 249 15.2 Ioc容器 250 15.2.1 BeanFactory 250 15.2.2 ApplicationContext 252 15.2.3 Beans的生命周期过程 253...

    JAVA核心知识点整理(有效)

    1. 目录 1. 2. 目录 .........................................................................................................................................................1 JVM ........................

Global site tag (gtag.js) - Google Analytics