Spring基础--整合MVC配置

Spring 如何与第三方MVC框架结合?

其实就是讨论如何加载ApplicationContext.xml的问题:

ApplicationContext是Spring的容器,负责管理所有的组件,从业务逻辑层组件,到持久层组件,都必须运行在Spring容器中。因此,必须在Web应用启动时,创建Spring的ApplicationContext实例。事实上,Spring ApplictionContext作为IoC容器,总应该优先加载。

不管采用怎样的方法,Spring容器都应该在应用启动时,自动加载。为了让Spring容器能自动加载,通常有如下做法:
一、采用ContextLoaderListener创建ApplicationContext
前提条件:必须服务器支持listener,下面这些服务器都是支持Listener:
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文件中增加如下一段即可:
<listener>
    <listener-class>org.springframework.web.context.ContextLoaderListener</listener-class>
</listener>
如果有多个配置文件需要载入,则考虑使用<context-param>元素来确定配置文件的文件名。ContextLoaderListener加载时,会查找名为contextConfigLocation的参数。因此,配置context-param时参数名字应该是contextConfigLocation。
带多个配置文件的web.xml文件如下:
<context-param>
  <!--  参数名为contextConfigLocation -->
  <param-name>contextConfigLocation</param-name>
  <!--  多个配置文件之间以,隔开 -->
  <param-value>/WEB-INF/daoContext.xml,/WEB-INF/applicationContext.xml</param-value>
</context-param>
 <!--  采用listener创建ApplicationContext实例-->
<listener>
        <listener-class>org.springframework.web.context.ContextLoaderListener</listener-class>
</listener>

如果没有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 class SpringTestServlet extends HttpServlet
{
 //Servlet的响应方法。
 public void service(HttpServletRequest request, HttpServletResponse response)
  throws ServletException,java.io.IOException
 {z
  //获取Servlet的ServletContext对象
  ServletContext sc = getServletContext();
  //使用WebApplicationContextUtils类获得ApplicationContext
  WebApplicationContext ctx = WebApplicationContextUtils.getWebApplicationContext(sc);
  //获取Servlet的页面输出流
  PrintWriter out = response.getWriter();
  //将ApplicationContext对象输出
  out.println(ctx);
 }
}
程序里手动获取ApplicationContext对象,然后直接输出到Servlet的响应。结果看到,ApplicationContext加载了web.xml文件中指定的两个配置文件。

二、采用ContextLoaderServlet创建ApplicationContext
如果容器不支持Listener,则只能使用load-on-startup Servlet创建ApplicationContext实例,下面的容器都不支持Listener:
1.BEA WebLogic up to 8.1 SP2。
2.IBM WebSphere 5.x 。
3.Oracle OC4J 9.0.3。
Spring提供了一个特殊的Servlet类:ContextLoaderServlet。该Servlet在启动时,会自动查找WEB-INF/下的applicationContext.xml文件。
当然,为了让ContextLoaderServlet随应用启动而启动,应将此Servlet配置成load-on-startup的Servlet,load-on-startup的值小一点比较合适,因为要保证ApplicationContext优先创建。如果只有一个配置文件,并且文件名为:applicationContext.xml。在web.xml文件中增加如下一段即可:
<servlet>
 <servlet-name>context</servlet-name>
 <servlet-class>org.springframework.web.context.ContextLoaderServlet</servlet-class>
 <load-on-startup>1</load-on-startup>
</servlet>
该Servlet用于提供“后台”服务,作为容器管理应用中的其他bean,不需要响应客户请求,因此无需配置servlet-mapping。

如果有多个配置文件,一样使用<context-param>元素来确定多个配置文件。

不管是ContextLoaderServlet,还是ContextLoaderListener,都依赖于ContextLoader创建ApplicationContext实例。在ContextLoader代码的第240行,有如下代码:
String configLocation = servletContext.getInitParameter(CONFIG_LOCATION_PARAM);
if (configLocation != null) {
 wac.setConfigLocations(StringUtils.tokenizeToStringArray(configLocation,
 ConfigurableWebApplicationContext.CONFIG_LOCATION_DELIMITERS));
}
其中CONFIG_LOCATION_PARAM是该类的常量,其值为contextConfigLocation。可看出:ContextLoader首先检查servletContext中是否有contextConfigLocation的参数,如果有该参数,则加载该参数指定的配置文件。带多参数的配置如下:
<context-param>
  <!--  参数名为contextConfigLocation -->
  <param-name>contextConfigLocation</param-name>
  <!--  多个配置文件之间以,隔开 -->
  <param-value>/WEB-INF/daoContext.xml,/WEB-INF/applicationContext.xml</param-value>
 </context-param>
 <!--  采用load-on-startup Servlet创建ApplicationContext实例-->
<servlet>
  <servlet-name>context</servlet-name>
  <servlet-class>org.springframework.web.context.ContextLoaderServlet</servlet-class>
  <!--  下面值小一点比较合适,会优先加载-->
  <load-on-startup>1</load-on-startup>
</servlet>

总结:
ContextLoaderServlet与ContextLoaderListener底层都依赖于ContextLoader。
因此,二者唯一的区别:是由于Servlet2.3的规范:listener比servlet优先加载。
因此,采用ContextLoaderListener创建ApplicationContext的时机更早。

当然,也可以通过ServletContext的getAttribute方法获取ApplicationContext,使用WebApplicationContextUtils类更便捷,因为无需记住ServletContext属性名。
即使ServletContext的WebApplicationContext.ROOT_WEB_APPLICATION_CONTEXT_ATTRIBUTE属性没有对应对象,WebApplicationContextUtils的getWebApplicationContext()方法将会返回空,而不会引起异常。

获得了WebApplicationContext实例的引用后,可以通过bean的名字访问容器中的bean实例。
大部分时候,无需通过这种方式访问容器中的bean。因为Spring容器将bean置入容器的管理中,客户端请求直接转发给容器中的bean,然后由容器管理bean之间的依赖。

你可能感兴趣的:(职场,休闲,spring基础,整合MVC配置)