2007-05-21
关于Spring中的父容器和子容器
spring参考文档中很多地方提到了父容器和子容器的概念,在使用的时候往往是将有关的xml配置文件放在一起配置,如:
<context-param>
<param-name>contextConfigLocation</param-name>
<param-value>
/WEB-INF/applicationContext.xml,
/ WEB-INF/classes/com/**/*.xml,
/WEB-INF/classes/com/**/*.xml,
</param-value>
</context-param>
那么在程序运行时,怎么区分父容器和子容器,是按照配置文件的顺序吗?
<context-param>
<param-name>contextConfigLocation</param-name>
<param-value>
/WEB-INF/applicationContext.xml,
/ WEB-INF/classes/com/**/*.xml,
/WEB-INF/classes/com/**/*.xml,
</param-value>
</context-param>
那么在程序运行时,怎么区分父容器和子容器,是按照配置文件的顺序吗?
- 23:36
- 浏览 (1196)
- 评论 (2)
- 分类: struts+spring+hibernate
- 进入论坛
- 相关推荐
评论
calmness
2007-05-22
protected WebApplicationContext createWebApplicationContext(
ServletContext servletContext, ApplicationContext parent) throws BeansException {
Class contextClass = determineContextClass(servletContext);
if (!ConfigurableWebApplicationContext.class.isAssignableFrom(contextClass)) {
throw new ApplicationContextException("Custom context class [" + contextClass.getName() +
"] is not of type ConfigurableWebApplicationContext");
}
ConfigurableWebApplicationContext wac =
(ConfigurableWebApplicationContext) BeanUtils.instantiateClass(contextClass);
wac.setParent(parent);
wac.setServletContext(servletContext);
//获取spring配置文件信息,在web.xml中的contextConfigLocation中
String configLocation = servletContext.getInitParameter(CONFIG_LOCATION_PARAM);
if (configLocation != null) {
wac.setConfigLocations(StringUtils.tokenizeToStringArray(configLocation,
ConfigurableWebApplicationContext.CONFIG_LOCATION_DELIMITERS));
}
wac.refresh();
return wac;
}
这里一次性读取了contextConfigLocation下的所有配置文件,然后wac.refresh()中将这些配置进行解释注册到一个beanfactory中,所以在这里是没有区分父子的,这些配置都会注册到同一个容器当中。
再来看看refresh方法,由于spring内部的类层次比较复杂,在此就直接列出它最终调用的那个refresh方法:
public void refresh() throws BeansException, IllegalStateException {
synchronized (this.startupShutdownMonitor) {
this.startupTime = System.currentTimeMillis();
//初始化context内部的beanfactory
refreshBeanFactory();
ConfigurableListableBeanFactory beanFactory = getBeanFactory();
// Populate the bean factory with context-specific resource editors.
ConfigurableBeanFactoryUtils.registerResourceEditors(beanFactory, this);
beanFactory.registerCustomEditor(Class.class, new ClassEditor(getClassLoader()));
// Configure the bean factory with context semantics.
beanFactory.addBeanPostProcessor(new ApplicationContextAwareProcessor(this));
beanFactory.ignoreDependencyInterface(ResourceLoaderAware.class);
beanFactory.ignoreDependencyInterface(ApplicationEventPublisherAware.class);
beanFactory.ignoreDependencyInterface(MessageSourceAware.class);
beanFactory.ignoreDependencyInterface(ApplicationContextAware.class);
// Allows post-processing of the bean factory in context subclasses.
postProcessBeanFactory(beanFactory);
// Invoke factory processors registered with the context instance.
for (Iterator it = getBeanFactoryPostProcessors().iterator(); it.hasNext();) {
BeanFactoryPostProcessor factoryProcessor = (BeanFactoryPostProcessor) it.next();
factoryProcessor.postProcessBeanFactory(beanFactory);
}
if (logger.isInfoEnabled()) {
if (getBeanDefinitionCount() == 0) {
logger.info("No beans defined in application context [" + getDisplayName() + "]");
}
else {
logger.info(getBeanDefinitionCount() + " beans defined in application context [" + getDisplayName() + "]");
}
}
// Invoke factory processors registered as beans in the context.
invokeBeanFactoryPostProcessors();
// Register bean processors that intercept bean creation.
registerBeanPostProcessors();
// Initialize message source for this context.
initMessageSource();
// Initialize event multicaster for this context.
initApplicationEventMulticaster();
// Initialize other special beans in specific context subclasses.
onRefresh();
// Check for listener beans and register them.
registerListeners();
// Instantiate singletons this late to allow them to access the message source.
beanFactory.preInstantiateSingletons();
// Last step: publish corresponding event.
publishEvent(new ContextRefreshedEvent(this));
}
}
后面的不管它,只需要看refreshBeanFactory()这个方法,这里实际上就是创建一个新的beanfactory,然后将web.xml中设置的几个配置文件进行解释和注册:
protected final void refreshBeanFactory() throws BeansException {
// Shut down previous bean factory, if any.
if (this.beanFactory != null) {
this.beanFactory.destroySingletons();
this.beanFactory = null;
}
// Initialize fresh bean factory.
try {
//创建新的beanfactory
DefaultListableBeanFactory beanFactory = createBeanFactory();
//加载bean定义到beanfactory
loadBeanDefinitions(beanFactory);
this.beanFactory = beanFactory;
if (logger.isInfoEnabled()) {
logger.info("Bean factory for application context [" + getDisplayName() + "]: " + beanFactory);
}
}
catch (IOException ex) {
throw new ApplicationContextException(
"I/O error parsing XML document for application context [" + getDisplayName() + "]", ex);
}
}
初始化web容器时,实际上只用了一个beanFactory加载了在contextConfigLocation下配置的所有xml,所以这里并无父子容器之分。详细如何解释加载,LZ可自行去看,在此就不多说了。
xly_971223
2007-05-22
我的理解是:随便从那个文件加载都可以,遇到依赖的bean就去查找然后加载 如此递归直到所有的bean加载完毕。
没读过spring源码 自己理解的
可以去看看源码就明白
没读过spring源码 自己理解的
可以去看看源码就明白
- 浏览: 1832 次
- 性别:

- 来自: 北京

- 详细资料
搜索本博客
最新评论
-
计算两个日期间相隔的周数
weeks
-- by failure5152 -
Java中用类名做变量名
编译器 应该提示错误吧
-- by sandybuster -
利用js模拟HashMap
var jsMap={ Map:{}, set:function (key, ...
-- by dangzhao -
Java中用类名做变量名
你再反编译一下看看,就知道编译器干啥了,呵呵
-- by xiaoych -
Java中用类名做变量名
你不要自己迷惑自己.按照代码规范写代码
-- by hgq0011






评论排行榜