<?xml version="1.0" encoding="UTF-8"?>
<rss version="2.0"
	xmlns:content="http://purl.org/rss/1.0/modules/content/"
	xmlns:wfw="http://wellformedweb.org/CommentAPI/"
	xmlns:dc="http://purl.org/dc/elements/1.1/"
	xmlns:atom="http://www.w3.org/2005/Atom"
	xmlns:sy="http://purl.org/rss/1.0/modules/syndication/"
	xmlns:slash="http://purl.org/rss/1.0/modules/slash/"
	>

<channel>
	<title>ChenTaoqian&#039;s Blog &#187; Spring</title>
	<atom:link href="http://www.chentaoqian.com/archives/category/compute/spring/feed" rel="self" type="application/rss+xml" />
	<link>http://www.chentaoqian.com</link>
	<description>主机,企业邮箱,域名,空间,服务器,Java,Oracle,PHP,Linux,JS,MySQL,Apache</description>
	<lastBuildDate>Wed, 30 Nov 2011 14:35:01 +0000</lastBuildDate>
	<generator>http://wordpress.org/?v=2.9.2</generator>
	<language>en</language>
	<sy:updatePeriod>hourly</sy:updatePeriod>
	<sy:updateFrequency>1</sy:updateFrequency>
			<item>
		<title>WebApplicationContext之于Spring</title>
		<link>http://www.chentaoqian.com/archives/343</link>
		<comments>http://www.chentaoqian.com/archives/343#comments</comments>
		<pubDate>Fri, 19 Jun 2009 12:56:15 +0000</pubDate>
		<dc:creator>admin</dc:creator>
				<category><![CDATA[Spring]]></category>
		<category><![CDATA[webApplicationContext]]></category>
		<category><![CDATA[容器]]></category>

		<guid isPermaLink="false">http://www.chentaoqian.com/?p=343</guid>
		<description><![CDATA[ApplicationContext是Spring的核心，Context我们通常解释为上下文环境，我想用“容器”来表述它更容易理解一些，ApplicationContext则是“应用的容器”了:P，Spring把Bean放在这个容器中，在需要的时候，用getBean方法取出，虽然我没有看过这一部分的源代码，但我想它应该是一个类似Map的结构。
在Web应用中，我们会用到WebApplicationContext，WebApplicationContext继承自ApplicationContext，先让我们看看在Web应用中，怎么初始化WebApplicationContext，在web.xml中定义:


Java代码 


&#60;context-param&#62;    
&#60;param-name&#62;contextConfigLocation&#60;/param-name&#62;    
&#60;param-value&#62;/WEB-INF/applicationContext.xml&#60;/param-value&#62;    
&#60;/context-param&#62;    
  
&#60;listener&#62;    
&#60;listener-class&#62;org.springframework.web.context.ContextLoaderListener&#60;/listener-class&#62;    
&#60;/listener&#62;    
  
&#60;!&#8211; OR USE THE CONTEXTLOADERSERVLET INSTEAD OF THE LISTENER    
&#60;servlet&#62;    
&#60;servlet-name&#62;context&#60;/servlet-name&#62;    
&#60;servlet-class&#62;org.springframework.web.context.ContextLoaderServlet&#60;/servlet-class&#62;    
&#60;load-on-startup&#62;1&#60;/load-on-startup&#62;    
&#60;/servlet&#62;    
&#8211;&#62;   


&#60;context-param&#62;
&#60;param-name&#62;contextConfigLocation&#60;/param-name&#62;
&#60;param-value&#62;/WEB-INF/applicationContext.xml&#60;/param-value&#62;
&#60;/context-param&#62; 

&#60;listener&#62;
&#60;listener-class&#62;org.springframework.web.context.ContextLoaderListener&#60;/listener-class&#62;
&#60;/listener&#62; 

&#60;!-- OR USE THE CONTEXTLOADERSERVLET INSTEAD OF THE LISTENER
&#60;servlet&#62;
&#60;servlet-name&#62;context&#60;/servlet-name&#62;
&#60;servlet-class&#62;org.springframework.web.context.ContextLoaderServlet&#60;/servlet-class&#62;
&#60;load-on-startup&#62;1&#60;/load-on-startup&#62;
&#60;/servlet&#62;
--&#62;
可以看出，有两种方法，一个是用ContextLoaderListener这个Listerner，另一个是ContextLoaderServlet这个Servlet，这两个方法都是在web应用启动的时候来初始化WebApplicationContext，我个人认为Listerner要比Servlet更好一些，因为Listerner监听应用的启动和结束，而Servlet得启动要稍微延迟一些，如果在这时要做一些业务的操作，启动的前后顺序是有影响的。
那么在ContextLoaderListener和ContextLoaderServlet中到底做了什么呢？
以ContextLoaderListener为例，我们可以看到


Java代码 


public void contextInitialized(ServletContextEvent event) {    
this.contextLoader = createContextLoader();    
this.contextLoader.initWebApplicationContext(event.getServletContext());    
}    
protected ContextLoader createContextLoader() {    
return new ContextLoader();    
}   


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的配置变成类似下面的样子


Java代码 


&#60;action attribute=&#8220;aForm&#8221; name=&#8220;aForm&#8221; path=&#8220;/aAction&#8221; scope=&#8220;request&#8221; type=&#8220;org.springframework.web.struts.DelegatingActionProxy&#8221;&#62;    
&#60;forward name=&#8220;forward&#8221; path=&#8220;forward.jsp&#8221; /&#62;    
&#60;/action&#62;   


&#60;action attribute="aForm" name="aForm" path="/aAction" scope="request" type="org.springframework.web.struts.DelegatingActionProxy"&#62;
&#60;forward name="forward" path="forward.jsp" /&#62;
&#60;/action&#62;
注意type变成了org.springframework.web.struts.DelegatingActionProxy，之后我们需要建立action-servlet.xml这样的文件，action-servlet.xml符合Spring的spring-beans.dtd标准，在里面定义类似下面的


Java代码 


&#60;bean name=&#8220;/aAction&#8221; class=&#8220;com.web.action.Aaction&#8221; singleton=&#8220;false&#8221;&#62;  [...]]]></description>
		<wfw:commentRss>http://www.chentaoqian.com/archives/343/feed</wfw:commentRss>
		<slash:comments>0</slash:comments>
		</item>
		<item>
		<title>Spring的分模块开发(Context的分级机制)</title>
		<link>http://www.chentaoqian.com/archives/93</link>
		<comments>http://www.chentaoqian.com/archives/93#comments</comments>
		<pubDate>Fri, 05 Jun 2009 14:26:25 +0000</pubDate>
		<dc:creator>admin</dc:creator>
				<category><![CDATA[Spring]]></category>

		<guid isPermaLink="false">http://www.chentaoqian.com/?p=93</guid>
		<description><![CDATA[spring 分模块开发
使用不同的两个 context.xml 配置文件new出来的Context就是不同的Context他们之间不可以进行Bean的互访.只能访问相同的父级Context.
背景
      我们一般采用spring+Struts+ibatis的开发模式，使用spring统管业务bean，当项目很大时，面临一个bean命名冲突问题，如果和struts一样，采取分模块的方式，不同的模块有自己的命名空间，将会避免几个并行开发的子系统或模块共用一套bean配置文件时id产生重名的问题。
简单方案
     整个系统所使用的公共bean，例如数据源、事务管理、iBatis或Hibernate的引擎、国际化资源文件等，放在一个root context文件中， 构造一个根ApplicationContext实例，作为各子模块的父,这里就看出Spring设计上的易扩展性了，ApplicationContext的构造子允许通过一个父实例来创建。
   
    核心类 ContextHelper ,作为管理器类，如下：
    
 public class ContextHelper {
 
    // 不同的环境有不同的配置文件
 
    private static Map _contexts ; //环境容器
    private static ApplicationContext _rootContext; //根环境
    private static final String ROOT_CONTEXT = &#8220;conf/rootContext.XML&#8221;; //根环境的配置文件
 
   static {
      _contexts = new HashMap();
      try{
        _rootContext = new ClassPathXmlApplicationContext(ROOT_CONTEXT); //创建根环境
      } catch (Exception e) {
        throw new ContextException(e);
      [...]]]></description>
		<wfw:commentRss>http://www.chentaoqian.com/archives/93/feed</wfw:commentRss>
		<slash:comments>0</slash:comments>
		</item>
		<item>
		<title>Spring整合第三方MVC框架的通用配置</title>
		<link>http://www.chentaoqian.com/archives/91</link>
		<comments>http://www.chentaoqian.com/archives/91#comments</comments>
		<pubDate>Fri, 05 Jun 2009 14:21:20 +0000</pubDate>
		<dc:creator>admin</dc:creator>
				<category><![CDATA[Spring]]></category>
		<category><![CDATA[mvc]]></category>
		<category><![CDATA[配置]]></category>

		<guid isPermaLink="false">http://www.chentaoqian.com/?p=91</guid>
		<description><![CDATA[      如果需要使用第三方MVC框架，则不能在web.xml文件中配置ApplicationContext的启动。但是， ApplicationContext是Spring的容器，负责管理所有的组件，从业务逻辑层组件，到持久层组件，都必须运行在Spring容器中。因此，必须在Web应用启动时，创建Spring的ApplicationContext实例。事实上，Spring ApplictionContext作为IoC容器，总应该优先加载。
不管采用怎样的方法，Spring容器都应该在应用启动时，自动加载。为了让Spring容器能自动加载，通常有两个做法：
1.让MVC框架负责创建ApplicationContext实例，MVC框架加载时自动创建Spring容器。Struts就是采用这种机制与Spring整合。
2.采用load-on-startup Servlet实现。
根据Servlet2.3标准，所有的ServletContextListener都会比Servlet优先加载——即使是load-on-startup Servlet。ApplicationContext实例是Spring容器，负责管理应用中所有的组件，包括业务逻辑层组件和持久层组件。因此，应该尽可能早的创建Spring容器。
为此，应该优先采用listener创建ApplicationContext。只是，ServletContextListener是从Servlet 2.3才出现的规范。如果使用了不支持Servlet2.3以上的Web服务器，则只能放弃ServletContextListener，采用load-on-startup Servlet策略。
Spring管理的组件相当多，如果将所有的组件部署在同一个配置文件里。不仅会降低配置文件的可读性，增大修改配置文件时引入错误的可能性，也不符合软件工程“分而治之”的规则。通常推荐服务层对象，业务逻辑对象，DAO对象都存在于互不相同的Context中，而表现层对象如Spring MVC控制器，则被配置在表现层Context中。甚至将某个特定模块的组件部署在单独的Context中。
实际的应用中，Spring的配置文件通常不只一个，而是按功能被分成多个。好在，所有负责加载Spring容器的工具都可同时加载多个配置文件。
一. 采用ContextLoaderListener创建ApplicationContext
使用ContextLoaderListener创建ApplicationContext必须服务器支持listener，下面这些服务器都是支持 Listener的，如果使用这些服务器，则可以使用ContextLoaderListener创建ApplicationContext实例：
1.Apache Tomcat 4.x+ 。
2.etty 4.x+ 。
3.Resin 2.1.8+ 。
4.Orion 2.0.2+ 。
5.BEA WebLogic 8.1 SP3。
Spring提供ServletContextListener的一个实现类ContextLoaderListener，该类可以作为listener 使用，它会在创建时候自动查找WEB-INF/下的applicationContext.xml文件，因此，如果只有一个配置文件，并且文件名为 applicationContext.xml，只需在web.xml文件中增加如下一段即可：
&#60;listener&#62;
    &#60;listener-class&#62;org.springframework.web.context.ContextLoaderListener&#60;/listener-class&#62;
&#60;/listener&#62;
如果有多个配置文件需要载入，则考虑使用&#60;context-param&#62;元素来确定配置文件的文件名。 ContextLoaderListener加载时，会查找名为contextConfigLocation的参数。因此，配置context- param时参数名字应该是contextConfigLocation。
带多个配置文件的web.xml文件如下：
&#60;!&#8211;  XML文件的文件头&#8211;&#62;
&#60;?xml version=&#8221;1.0&#8243; encoding=&#8221;ISO-8859-1&#8243;?&#62;
&#60;!&#8211;  web.xml文件的DTD等信息&#8211;&#62;
&#60;!DOCTYPE web-app
    PUBLIC &#8220;-//Sun Microsystems, Inc.//DTD Web Application 2.3//EN&#8221;
    &#8220;http://java.sun.com/dtd/web-app_2_3.dtd&#8221;&#62;
&#60;web-app&#62;
 &#60;!&#8211;  确定多个配置文件&#8211;&#62;
在web.xml文件中加载Spring容器，这是最常见的做法。Spring自己的MVC框架就是采用这种策略。
关于让MVC框架负责创建ApplicationContext实例的情况比较多，因为每个MVC框架的启动机制有区别，因此加载ApplicationContext的方式也各有不同。
对于在web.xml配置文件中配置ApplicationContext的自动创建有两种策略：
1.利用ServletContextListener实现。
&#60;context-param&#62;
  &#60;!&#8211;  参数名为contextConfigLocation &#8211;&#62;
  &#60;param-name&#62;contextConfigLocation&#60;/param-name&#62;
  &#60;!&#8211;  多个配置文件之间以,隔开 &#8211;&#62;
  &#60;param-value&#62;/WEB-INF/daoContext.xml,/WEB-INF/applicationContext.xml&#60;/param-value&#62;
 &#60;/context-param&#62;
 &#60;!&#8211;  采用listener创建ApplicationContext实例&#8211;&#62;
    &#60;listener&#62;
        &#60;listener-class&#62;org.springframework.web.context.ContextLoaderListener&#60;/listener-class&#62;
    &#60;/listener&#62;
&#60;/web-app&#62;
如果没有contextConfigLocation制定配置文件，Spring自动查找applicationContext.xml配置文件。
如果有contextConfigLocation，则利用该参数确定的配置文件，该参数指定的一个字符串，Spring的ContextLoaderListener负责将该字符串分解成多个配置文件，逗号“,”、空格“ ”、分号“;”都可作为字符串的分割符。
如果既然没有applicationContext.xml文件，也没有使用contextConfigLocation参数确定配置文件，或者 contextConfigLocation确定的配置文件不存在，都将导致：Spring无法加载配置文件，无法正常创建 ApplicationContext实例。
Spring根据bean定义创建 WebApplicationContext对象，并将其保存在Web应用的ServletContext中。大部分情况下，应用中的bean无需感受到ApplicationContext的存在，只要利用ApplicationContext的IoC即可。
如果需要在应用中获取ApplicationContext实例，可以通过如下方法获取：
WebApplicationContext ctx =
WebApplicationContextUtils.getWebApplicationContext(servletContext);
下面是采用Servlet获取ApplicationContext的完整源代码：
public [...]]]></description>
		<wfw:commentRss>http://www.chentaoqian.com/archives/91/feed</wfw:commentRss>
		<slash:comments>0</slash:comments>
		</item>
	</channel>
</rss>

