浏览 5896 次
锁定老帖子 主题:关于Spring中的父容器和子容器
精华帖 (0) :: 良好帖 (0) :: 新手帖 (0) :: 隐藏帖 (0)
|
|
---|---|
作者 | 正文 |
发表时间:2007-05-21
<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> 那么在程序运行时,怎么区分父容器和子容器,是按照配置文件的顺序吗? 声明:ITeye文章版权属于作者,受法律保护。没有作者书面许可不得转载。
推荐链接
|
|
返回顶楼 | |
发表时间:2007-05-22
我的理解是:随便从那个文件加载都可以,遇到依赖的bean就去查找然后加载 如此递归直到所有的bean加载完毕。
没读过spring源码 自己理解的 可以去看看源码就明白 |
|
返回顶楼 | |
发表时间: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可自行去看,在此就不多说了。 |
|
返回顶楼 | |