论坛首页 Java企业应用论坛

关于Spring中的父容器和子容器

浏览 5896 次
精华帖 (0) :: 良好帖 (0) :: 新手帖 (0) :: 隐藏帖 (0)
作者 正文
   发表时间:2007-05-21  
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>
那么在程序运行时,怎么区分父容器和子容器,是按照配置文件的顺序吗?
   发表时间:2007-05-22  
我的理解是:随便从那个文件加载都可以,遇到依赖的bean就去查找然后加载 如此递归直到所有的bean加载完毕。
没读过spring源码 自己理解的
可以去看看源码就明白
0 请登录后投票
   发表时间: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中
		[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;
	}


这里一次性读取了contextConfigLocation下的所有配置文件,然后wac.refresh()中将这些配置进行解释注册到一个beanfactory中,所以在这里是没有区分父子的,这些配置都会注册到同一个容器当中。

再来看看refresh方法,由于spring内部的类层次比较复杂,在此就直接列出它最终调用的那个refresh方法:


	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));
		}
	}


后面的不管它,只需要看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
			[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);
		}
	}


初始化web容器时,实际上只用了一个beanFactory加载了在contextConfigLocation下配置的所有xml,所以这里并无父子容器之分。详细如何解释加载,LZ可自行去看,在此就不多说了。
0 请登录后投票
论坛首页 Java企业应用版

跳转论坛:
Global site tag (gtag.js) - Google Analytics