What is a Context in Java and ApplicationContext vs WebApplicationContext

当我们开始使用Spring Framework时,能想到的最基本的问题是:ApplicationContext在spring中扮演什么的角色,它和WebApplicationContext有什么不同呢。在考虑这些之前,应该先知道What is a Context in Java

1.What is a Context in Java

A context可以被说成是被提供给当前工作单元的正运行的环境,它可以是环境变量、实例变量、类的状态等等。当我这么说的时候,我的意思是ServletContext 表示在它的容器内的servlet环境,与ApplicationContext 类似。而ApplicationContext 表示在spring容器内的Spring application’s核心环境。
所以类似的那有Servlet’s ServletContext, JSF’s FacesContext, Spring’s ApplicationContext, Android’s Context, JNDI’s InitialContext,这些context都遵循Facade Pattern去抽象这个环境的具体细节给终端用户,具体抽象的思想和做法是提供接口用于同终端用户交流沟通

2. Spring Context Configuration

In Spring web applications,有两个context会在服务开始的时候被初始化。他们中每个被不同地配置和初始化。一个是Application Context,另一个是Web Application Context

2.1 ApplicationContext

Application Context 被一个ContextLoaderListener or ContextLoaderServlet初始化,我们定义ContextLoaderListener or ContextLoaderServlet在我们应用的web.xml文件中并像下面展示的那样配置:

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

<context-param>
    <param-name>contextConfigLocation</param-name>
    <param-value>/WEB-INF/root-context.xml</param-value>
</context-param>

在上述配置中,我们正在请spring去加载root-context.xml并从它创建一个Application Context,如果contextConfigLocation在上面代码片段中没有提到,它默认查找/WEB-INF/applicationContext.xml。就像下面这样:

<listener>
    <listener-class>org.springframework.web.context.ContextLoaderListener</listener-class>
</listener>
  • [ ] 注意:There will be always be one application context per web application.
2.2 WebApplicationContext

WebApplicationContext是一个servlet-specific context ,它被配置在应用的web.xml*文件中的dispatcher servlets所加载,所以每个dispatcher servlet有它自己的从-servlet.xml文件初始化的servlet-context。这允许我们根据 the incoming requests based on the servlet’s url-pattern and handle them。这样的话,dispatcher servlets中的一个能通过Controller服务web页面,而另一个能被用于实现无状态的REST web service。综上,我们的理解是:一个web应用能有多个dispatcher-servlet configurations,因此也就有多个web-application contexts.

Web Application context extended Application Context which is designed to work with the standard javax.servlet.ServletContext so it’s able to communicate with the container.

public interface WebApplicationContext extends ApplicationContext {
    ServletContext getServletContext();
}

Beans, instantiated in WebApplicationContext will also be able to use ServletContext if they implement ServletContextAware interface

package org.springframework.web.context;
public interface ServletContextAware extends Aware { 
     void setServletContext(ServletContext servletContext);
}

如果我们想改变dispatcher-servlet文件的名字或改变他的位置,我们可以增加 init-param with contextConfigLocation as param-name,像下面代码:

<servlet>
    <servlet-name>mvc-dispatcher</servlet-name>
    <servlet-class>org.springframework.web.servlet.DispatcherServlet</servlet-class>
    <init-param>
        <param-name>contextConfigLocation</param-name>
        <param-value>/WEB-INF/sample-dispatcher-servlet.xml</param-value>
    </init-param>
    <load-on-startup>1</load-on-startup>
</servlet>

<servlet-mapping>
    <servlet-name>mvc-dispatcher</servlet-name>
    <url-pattern>/</url-pattern>
</servlet-mapping>

正如上述代码片段,spring没有发现名字为mvc-dispatcher-servlet.xml的dispatcher-servlet context文件,但是代替的它将为contextConfigLocation查找init-param属性指定的值,如:sample-dispatcher-servlet.xml

2.3 Difference between the two contexts

文章最重要的部分是what’s the difference between the two contexts

首先,正如上面已经提到的,ApplicationContext is the root-context,它有一些bean的配置,这些配置是我们可能想在整个应用中作为单例使用的(use/re-use)。在web应用中总会有且只有一个application context。然而,可以有多个WebApplicationContexts给我们指定在应用的web.xml中的每个dispatcher servlet

  • [ ] 注意:WebApplicationContext internally extends ApplicationContext, and as a child inherits all the beans from its parent. So we can also override the parent bean within our WebApplicationContext.

在服务中间件(如业务逻辑组件service、数据访问组件DAO,我们更应该在ApplicationContext XML定义他们)和web关联的组件(如controllers 和view-resolvers,我们更应该定义他们在各自的 dispatcher-servlet‘s WebApplicationContext)之间保持一个清晰的分离那是比较好的

  • [ ] 注意:At server startup, ContextLoaderListener instantiates beans defined in applicationContext.xml. After the completion of bean instantiation defined in applicationContext.xml then beans defined in springweb-servlet.xml are instantiated.
    So instantiation order is root is application context, then DispatcherServlet.

  • [ ] 注意:Configuring contextLoaderListener is completely optional. We can boot up a Spring application with just the dispatcher-servlet, without even configuring contextLoaderListener (that loads up the root-context).

原文:
http://www.jcombat.com/spring/applicationcontext-webapplicationcontext

参考:
1. http://stackoverflow.com/questions/3652090/difference-between-applicationcontext-xml-and-spring-servlet-xml-in-spring-frame
2. https://www.quora.com/What-is-the-difference-between-WebApplicationContext-and-ApplicationContext-Why-do-we-use-ContextLoaderListener-and-what-is-Listener-exactly-in-Spring
3. http://javarevisited.blogspot.com/2012/11/difference-between-beanfactory-vs-applicationcontext-spring-framework.html

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值