Re: 关于Spring中的父容器和子容器
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内部的beanfactoryrefreshBeanFactory();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 { //创建新的beanfactoryDefaultListableBeanFactory beanFactory = createBeanFactory(); //加载bean定义到beanfactoryloadBeanDefinitions(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可自行去看,在此就不多说了。
页:
[1]