applicationcontext param为什么称为容器

1203人阅读
java web开发(21)
&&&& 两者都是装入bean定义信息,装配bean,根据需要分发bean。但是ApplicationContext提供更多功能,它提供了bean工厂所没有的解析信息文本工具,包括对国际化的支持,提供了载入文件资源的通用方法,如载入图片,它可以用注册为监听器的bean发送事件。另外一个很重要的区别是单例bean被载入的方式不一样。bean工厂延迟载入所有的bean,直到getbean方法被调用,才被创建。而ApplicationContext会预装入所有的单例bean,确保需要的时候单例bean都已经准备好了,这样我们的应用就不需要等待这些单例bean被创建。
参考知识库
* 以上用户言论只代表其个人观点,不代表CSDN网站的观点或立场
访问:817925次
积分:11020
积分:11020
排名:第948名
原创:263篇
转载:11篇
评论:134条
(1)(1)(2)(2)(2)(1)(1)(2)(1)(36)(13)(11)(7)(1)(10)(12)(14)(1)(11)(14)(9)(41)(20)(1)(1)(2)(1)(6)(2)(10)(15)(4)(8)(10)(7)ApplicationContext 实例化后去哪里了?
假如我们在写一个基于Spring的普通应用程序,不管我们用了多么精妙的设计模式,进行了如何巧妙的设计,我们必须在某个地方执行这样的代码: ClassPathXmlApplicationContext appContext = new ClassPathXmlApplicationContext( new String[] {"applicationContext.xml", "applicationContext-part2.xml"}); appContext.getBean("&");
也许这样的代码算不上丑陋,但是它无疑破坏了程序的纯洁性和透明性。我们的应用程序开始显式地依赖SpringFramework,我们必须清楚地知道Spring的配置文件有哪几个,每个配置文件的加入或修改源代码,我们必须在某些代码模块里调用丑陋的getBean方法来创造对象。
但是所有的这些丑陋的事情似乎在我们的Web应用程序里消失啦,所有的代码都是那么干净,只有简单的get与set及接口之间的调用,我们不需要知道ApplicationContext,我们甚至不需要知道Spring。但是我们所有的对象却又是通过Spring的ApplicationContext来创造的!
看上去似乎很神奇,但是假如我们稍微思考一下,就会发现这是一件合情合理又如此简单的事情,呵呵,只有第一个想到这个方法的人才是伟大的。让我们仔细想一下普通应用程序和Web应用程序的最大区别在哪里?
其实真正的区别只有一个,普通应用程序是一个主动执行的程序,而Web应用程序却是被动的组件。这意味着Web应用程序无法自己主动去生成自己的线程去执行某项任务,而必须借用Web容器中的一个线程。想象一下一个简单的任务:我们想每隔一段时间执行一个任务,比如说在Console里打印出一行文字。在我们的Web应用程序里应该怎么完成?在我不知道Servlet Listener或Spring里提供的Schedule之前(其实Spring就是利用Servlet Listner初始化Application Context时启动schedule的),这么简单的任务在一个Web应用程序里竟然是不可想象。还记得我当时采用的是最傻的做法:写了一个单独的应用程序,在这应用程序的main函数里启动了timetask。
但是如果换一种角度来看,整个Web应用程序生活在容器里也给我们带来了额外的好处,当我们让出了对应用程序的控制权之后,我们可以让容器帮我们完成很多本来很难处理的事情。其实IOC容器的真正作用也在于此,当我们把我们的对象创建工作移交给IOC容器之后,我们发现整个程序变得如此清晰,如此透明,对象之间的关联、哪些类需要事务处理或AOP功能、哪些类要远程访问,所有这些复杂的事情在我们的程序里都不见了,我们只看到了简单的get和set。
也许废话太多,但我觉得经过这样分析,其实ApplicationContext之谜已经不再是谜了。真正的关键在于当我们的Web应用程序是被动的组件时,它除了可以错用容器的线程之外还可以错用其它一些东西。我们可以让容器来帮我们创建ApplicationContext,然后把它放在某个地方,然后在需要使用时让容器从这个地方把ApplicationContext读出来,并执行相应的Controller就可以了。 这个"某个地方"就是ServletContext,而这个创建ApplicationContext的地方就是Servlet Listner,而取到ApplicationContext的地方是我们的DispatcherServlet。
仔细想一下,其实Web服务器并没有什么了不起的地方,它只是一个Java程序,它只是会在启动的时候去ClassLoad某些指定文件夹下的lib或classes,它会读某个在WEB-INF下面一个叫做web.xml的配置文件,再做一些初始化工作。Servlet Listener就是这个初始化工作的重要一步,服务器会读出web.xml里配置好的所有listner,然后调用每个Listner的contextInitialized方法(它还会去调每个Servlet的init方法,不过把初始化方法写在Listner里才是天经地义的)。哈哈,这也正是Spring MVC创建ApplicationContext的最好时机,当我们在web.xml里配置好ContextLoaderListener的时候,Spring就完成了ApplicationContext的创建过程,如果有人想研究源代码的话可以去看一下,不过这个创建过程并不象想象中的那么有趣,只是通过Class.forName和BeanUtils.instantiateClass创建出一个WebApplicationContext,然后再读了一下IOC容器的配置文件。 接下来的一个问题是我们要把创建的ApplicationContext放在哪里?答案是ServletContext,其实没必须对ServletContext进行深究,它只是可以一个可以全局存放Web应用程序的场所,我们只要想象成一个全局的HashMap就可以了,我们可以要把它put进去,就可以在Servlet或其它地方把它get出来。
Web服务器还要干的一件事件当然是在某个request到来时,它会启动一个单独的线程(这也是为何Webwork可以把Context放到ThreadLocal里的原因),根据web.xml里的配置和request的URI匹配去执行相应的Servlet。由于Servlet可以很轻松地读到ServletContext,当然也可以很轻松地读到ApplicationContext啦。接下来的事情就比想象中要简单啦,经过一些准备工作之后ApplicationContext中的URLMapping里配置好的某个Controller,执行一下再rend某个view就可以了。其实struts或webwork2的执行过程也是如此,所以MVC framwork分析透了其实真没什么了不起,远比O/R Mapping或其它的framework简单。虽然MVC的执行过程如此简单,但是我们还需要了解一些细节上的事件,所以让我们下次来讨论一下Spring MVC framework的执行过程吧。
在contextloader 类里面可以看大一段代码:
this.context = createWebApplicationContext(servletContext, parent);&&&servletContext.setAttribute(&&&&&WebApplicationContext.ROOT_WEB_APPLICATION_CONTEXT_ATTRIBUTE, this.context);
如此就明白了, spring的整个框架基础 是在 servlet 标准里面的一个扩展应用罢了, 不那么神奇了
参考知识库
* 以上用户言论只代表其个人观点,不代表CSDN网站的观点或立场
访问:45053次
排名:千里之外
原创:47篇
转载:13篇
评论:10条
(2)(7)(5)(3)(2)(2)(4)(2)(2)(7)(7)(17)初探spring applicationContext在web器皿中加载过程 - Web前端当前位置:& &&&初探spring applicationContext在web器皿中加载过程初探spring applicationContext在web器皿中加载过程&&网友分享于:&&浏览:7次初探spring applicationContext在web容器中加载过程
&context-param&
&param-name&webAppRootKey&/param-name&
&param-value&task.root&/param-value&
&/context-param&
&!-- 定义SPRING配置文件 --&
&context-param&
&param-name&contextConfigLocation&/param-name&
&param-value&/WEB-INF/taskContext*.xml&/param-value&
&/context-param&
&context-param&
&param-name&log4jConfigLocation&/param-name&
&param-value&/WEB-INF/log4j.properties&/param-value&
&/context-param&
&!-- 定义LOG4J监听器 --&
&listener&
&listener-class&org.springframework.web.util.Log4jConfigListener&/listener-class&
&/listener&
&!-- 定义SPRING监听器 --&
&listener&
&listener-class&org.springframework.web.context.ContextLoaderListener&/listener-class&
&/listener&
进入contextLoaderListener看看到底加载时做了甚么 ==&org.springframework.web.context.ContextLoaderListener
ContextLoaderListener implements
ServletContextListener {
ContextLoader contextL
* Initialize the root web application context.
//当WEB上下文初始化时,系统会调用此方法
contextInitialized(ServletContextEvent event) {
this.contextLoader = createContextLoader();
//监听到WEB上下文初始化的时候执行SPRING上下文contextLoader的初始化工作
this.contextLoader.initWebApplicationContext(event.getServletContext());
* Create the ContextLoader to use. Can be overridden in subclasses.
* @return the new ContextLoader
ContextLoader createContextLoader() {
ContextLoader();
* Return the ContextLoader used by this listener.
ContextLoader getContextLoader() {
* Close the root web application context.
contextDestroyed(ServletContextEvent event) {
(this.contextLoader != null
this.contextLoader.closeWebApplicationContext(event.getServletContext());
看一下是怎么来初始化webapplicationContext的 ==&contextLoader.initWebApplicationContext
WebApplicationContext initWebApplicationContext(ServletContext servletContext)
IllegalStateException, BeansException {
(servletContext.getAttribute(WebApplicationContext.ROOT_WEB_APPLICATION_CONTEXT_ATTRIBUTE) != null
IllegalStateException(
"Cannot initialize context because there is already a root application context
present - " +
"check whether you have multiple ContextLoader* definitions in your web.xml!"
startTime = System.currentTimeMillis();
(logger.isInfoEnabled()) {
("Root WebApplicationContext: initialization started"
servletContext.log("Loading Spring root WebApplicationContext"
// Determine parent for root web application context, if any.
ApplicationContext parent = loadParentContext(servletContext);
// Store context in local instance variable, to guarantee that
// it is available on ServletContext shutdown.
//创建web上下文
this.context = createWebApplicationContext(servletContext, parent);
servletContext.setAttribute(
WebApplicationContext.ROOT_WEB_APPLICATION_CONTEXT_ATTRIBUTE, this.context);
(logger.isInfoEnabled()) {
("Using context class ["
+ this.context.getClass().getName() +
"] for root WebApplicationContext"
(logger.isDebugEnabled()) {
logger.debug("Published root WebApplicationContext ["
+ this.context +
"] as ServletContext attribute with name ["
WebApplicationContext.ROOT_WEB_APPLICATION_CONTEXT_ATTRIBUTE + "]"
(logger.isInfoEnabled()) {
elapsedTime = System.currentTimeMillis() - startT
("Root WebApplicationContext: initialization completed in "
+ elapsedTime + "
(RuntimeException ex) {
logger.error("Context initialization failed"
servletContext.setAttribute(WebApplicationContext.ROOT_WEB_APPLICATION_CONTEXT_ATTRIBUTE, ex);
(Error err) {
logger.error("Context initialization failed"
servletContext.setAttribute(WebApplicationContext.ROOT_WEB_APPLICATION_CONTEXT_ATTRIBUTE, err);
==&contextLoader.createWebApplicationContext(servletContext, parent);
WebApplicationContext createWebApplicationContext(
ServletContext servletContext, ApplicationContext parent) throws
BeansException {
//根据servletContext来决定要实例化的WebApplicationContext
Class contextClass = determineContextClass(servletContext);
(!ConfigurableWebApplicationContext.class.isAssignableFrom(contextClass)) {
ApplicationContextException("Custom context class ["
+ contextClass.getName() +
"] is not of type ConfigurableWebApplicationContext"
ConfigurableWebApplicationContext wac =
(ConfigurableWebApplicationContext) BeanUtils.instantiateClass(contextClass);
wac.setParent(parent);
wac.setServletContext(servletContext);
//得到WEB.XML中设置的SPRING配置文件位置
String configLocation = servletContext.getInitParameter(CONFIG_LOCATION_PARAM);
(configLocation != null
//把配置文件分段后设置到WebApplicationContext的ConfigLocations中
wac.setConfigLocations(StringUtils.tokenizeToStringArray(configLocation,
ConfigurableWebApplicationContext.CONFIG_LOCATION_DELIMITERS));
//刷新WebApplicationContext
wac.refresh();
==&contextLoader.determineContextClass(servletContext);
Class determineContextClass(ServletContext servletContext) throws
ApplicationContextException {
//获得需要实例化的CONTEXT类名,在web.xml中有设置,如果没有设置,那么为空
String contextClassName = servletContext.getInitParameter(CONTEXT_CLASS_PARAM);
(contextClassName != null
ClassUtils.forName(contextClassName);
(ClassNotFoundException ex) {
ApplicationContextException(
"Failed to load custom context class ["
+ contextClassName + "]"
//如果在spring web.xml中没有设置context类位置,那么取得默认context
//取得defaultStrategies配置文件中的WebApplicationContext属性
contextClassName = defaultStrategies.getProperty(WebApplicationContext.class.getName());
ClassUtils.forName(contextClassName);
(ClassNotFoundException ex) {
ApplicationContextException(
"Failed to load default context class ["
+ contextClassName + "]"
SPRING上下文默认的策略是甚么呢? ==&contextLoader.defaultStrategies
Properties defaultS
// Load default strategy implementations from properties file.
// This is currently strictly internal and not meant to be customized
// by application developers.
//设置classpath为contextLoader同级目录
ClassPathResource resource = new
ClassPathResource(DEFAULT_STRATEGIES_PATH, ContextLoader.class);
//加载该目录下的所有properties文件
defaultStrategies = PropertiesLoaderUtils.loadProperties(resource);
(IOException ex) {
IllegalStateException("Could not load 'ContextLoader.properties': "
+ ex.getMessage());
找到同级目录下的配置文件 ==&ContextLoader.properties
# Default WebApplicationContext implementation class
ContextLoader.
# Used as fallback when no explicit context implementation has been specified as context-param.
# Not meant to be customized by application developers.
#默认的WebApplicationContext为org.springframework.web.context.support.XmlWebApplicationContext
org.springframework.web.context.WebApplicationContext=org.springframework.web.context.support.XmlWebApplicationContext
==&org.springframework.web.context.support.XmlWebApplicationContext
XmlWebApplicationContext extends
AbstractRefreshableWebApplicationContext {
/** Default config location for the root context */
//配置了默认的spring配置文件
String DEFAULT_CONFIG_LOCATION = "/WEB-INF/applicationContext.xml"
//配置文件默认BUILD路径
String DEFAULT_CONFIG_LOCATION_PREFIX = "/WEB-INF/"
//配置文件默认后缀名
String DEFAULT_CONFIG_LOCATION_SUFFIX = ".xml"
* Loads the bean definitions via an XmlBeanDefinitionReader.
* @see org.springframework.beans.factory.xml.XmlBeanDefinitionReader
* @see #initBeanDefinitionReader
* @see #loadBeanDefinitions
//获得bean配置
loadBeanDefinitions(DefaultListableBeanFactory beanFactory) throws
IOException {
//从BEAN工厂获得一个XmlBeanDefinitionReader 来读取SPRING配置文件
XmlBeanDefinitionReader beanDefinitionReader = new
XmlBeanDefinitionReader(beanFactory);
//设置beanDefinitionReader服务于当前CONTEXT
// resource loading environment.
beanDefinitionReader.setResourceLoader(this
beanDefinitionReader.setEntityResolver(new
ResourceEntityResolver(this
// Allow a subclass to provide custom initialization of the reader,
// then proceed with actually loading the bean definitions.
initBeanDefinitionReader(beanDefinitionReader);
//读取配置文件
loadBeanDefinitions(beanDefinitionReader);
* Initialize the bean definition reader used for loading the bean
* definitions of this context. Default implementation is empty.
* &p&Can be overridden in subclasses, e.g. for turning off XML validation
* or using a different XmlBeanDefinitionParser implementation.
* @param beanDefinitionReader the bean definition reader used by this context
* @see org.springframework.beans.factory.xml.XmlBeanDefinitionReader#setValidationMode
* @see org.springframework.beans.factory.xml.XmlBeanDefinitionReader#setDocumentReaderClass
initBeanDefinitionReader(XmlBeanDefinitionReader beanDefinitionReader) {
* Load the bean definitions with the given XmlBeanDefinitionReader.
* &p&The lifecycle of the bean factory is handled by the refreshBeanF
* therefore this method is just supposed to load and/or register bean definitions.
* &p&Delegates to a ResourcePatternResolver for resolving location patterns
* into Resource instances.
* @throws org.springframework.beans.BeansException in case of bean registration errors
* @throws java.io.IOException if the required XML document isn't found
* @see #refreshBeanFactory
* @see #getConfigLocations
* @see #getResources
* @see #getResourcePatternResolver
//读取配置文件
loadBeanDefinitions(XmlBeanDefinitionReader reader) throws
BeansException, IOException {
String[] configLocations = getConfigLocations();
(configLocations != null
i = 0; i & configLocations. i++) {
reader.loadBeanDefinitions(configLocations[i]);
* The default location for the root context is "/WEB-INF/applicationContext.xml",
* and "/WEB-INF/test-servlet.xml" for a context with the namespace "test-servlet"
* (like for a DispatcherServlet instance with the servlet-name "test").
//获得默认的ConfigLocations
String[] getDefaultConfigLocations() {
(getNamespace() != null
String[] {
DEFAULT_CONFIG_LOCATION_PREFIX + getNamespace() +
DEFAULT_CONFIG_LOCATION_SUFFIX}
String[] {
DEFAULT_CONFIG_LOCATION}
12345678910
12345678910
12345678910 上一篇:下一篇:文章评论相关解决方案 12345678910 Copyright & &&版权所有使用监听器listener来加载spring的配置文件:如下
&context-param&
&param-name&contextConfigLocation&/param-name&
&param-value&classpath:spring-beans.xml&/param-value&
&/context-param&
&listener&
&listener-class&org.springframework.web.context.ContextLoaderListener&/listener-class&
&/listener&
Spring会创建一个WebApplicationContext的上下文,称为父上下文(父容器),key是WebApplicationContext.ROOT_WEB_APPLICATION_CONTEXT_ATTRIBUTE,保存在ServletContext(Servlet上下文全局)中
可以使用Spring提供的工具类取出上下文对象:
WebApplicationContextUtils.getWebApplicationContext(ServletContext);
DispatcherServlet是一个Servlet,可以配置多个,每个DispatcherServlet有一个自己的上下文对象(WebApplictionContext)
称为子上下文(子容器),子上下文可以访问父上下文中的内容,但是父上下文不能范文子上下文中的内容,他也保存在ServletContext中
key是:"org.springframework.web.serrvlet.FrameworkServlet.CONTEXT"+Servlet名字,
当一个Request对象产生是会把这个自上下文对象(WebApplicationContext)保存在Request对象中,
key是DispatcherServlet.class.getName()+"CONTEXT";
可以通过使用工具类获取上下文:RequestContextUtils.getWebApplicationContext(request);
说明:spring并没有限制我们,必须使用父子上下文,我们可以自己决定如何时候如何使用
方案一:使用传统的父子容器的概念:分为controler,service,dao,这些层,service负者业务逻辑并管理事物,dao负责持久
方案二:小项目情况,不需要service,dao,将事物的控制加到controller中,只用springmvc的子容器,web.xml文件中不使用
    listener监听器来加载spring的配置文件,只使用DispatcherServlet来加载spring的配置,不需要父容器,只使用
    DispatcherServlet,事情就简单了,什么麻烦事都没有。(不推荐:只是为了说明sping的容器)
阅读(...) 评论()}

我要回帖

更多关于 applicationcontext包 的文章

更多推荐

版权声明:文章内容来源于网络,版权归原作者所有,如有侵权请点击这里与我们联系,我们将及时删除。

点击添加站长微信