[code]
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中
[color=red]String configLocation = servletContext.getInitParameter(CONFIG_LOCATION_PARAM);
if (configLocation != null) {
wac.setConfigLocations(StringUtils.tokenizeToStringArray(configLocation,
ConfigurableWebApplicationContext.CONFIG_LOCATION_DELIMITERS));
}
wac.refresh(); [/color]
return wac;
}
[/code]
这里一次性读取了contextConfigLocation下的所有配置文件,然后wac.refresh()中将这些配置进行解释注册到一个beanfactory中,所以在这里是没有区分父子的,这些配置都会注册到同一个容器当中。
再来看看refresh方法,由于spring内部的类层次比较复杂,在此就直接列出它最终调用的那个refresh方法:
[code]
public void refresh() throws BeansException, IllegalStateException {
synchronized (this.startupShutdownMonitor) {
this.startupTime = System.currentTimeMillis();
//初始化context内部的beanfactory
[color=red]refreshBeanFactory();[/color]
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));
}
}
[/code]
后面的不管它,只需要看refreshBeanFactory()这个方法,这里实际上就是创建一个新的beanfactory,然后将web.xml中设置的几个配置文件进行解释和注册:
[code]
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
[color=red]loadBeanDefinitions(beanFactory);[/color]
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);
}
}
[/code]
初始化web容器时,实际上只用了一个beanFactory加载了在contextConfigLocation下配置的所有xml,所以这里并无父子容器之分。详细如何解释加载,LZ可自行去看,在此就不多说了。
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中
[color=red]String configLocation = servletContext.getInitParameter(CONFIG_LOCATION_PARAM);
if (configLocation != null) {
wac.setConfigLocations(StringUtils.tokenizeToStringArray(configLocation,
ConfigurableWebApplicationContext.CONFIG_LOCATION_DELIMITERS));
}
wac.refresh(); [/color]
return wac;
}
[/code]
这里一次性读取了contextConfigLocation下的所有配置文件,然后wac.refresh()中将这些配置进行解释注册到一个beanfactory中,所以在这里是没有区分父子的,这些配置都会注册到同一个容器当中。
再来看看refresh方法,由于spring内部的类层次比较复杂,在此就直接列出它最终调用的那个refresh方法:
[code]
public void refresh() throws BeansException, IllegalStateException {
synchronized (this.startupShutdownMonitor) {
this.startupTime = System.currentTimeMillis();
//初始化context内部的beanfactory
[color=red]refreshBeanFactory();[/color]
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));
}
}
[/code]
后面的不管它,只需要看refreshBeanFactory()这个方法,这里实际上就是创建一个新的beanfactory,然后将web.xml中设置的几个配置文件进行解释和注册:
[code]
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
[color=red]loadBeanDefinitions(beanFactory);[/color]
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);
}
}
[/code]
初始化web容器时,实际上只用了一个beanFactory加载了在contextConfigLocation下配置的所有xml,所以这里并无父子容器之分。详细如何解释加载,LZ可自行去看,在此就不多说了。