【spring源代码】AbstractRefreshableApplicationContext类解析

/**
	 * This implementation performs an actual refresh of this context's underlying
	 * bean factory, shutting down the previous bean factory (if any) and
	 * initializing a fresh bean factory for the next phase of the context's lifecycle.
	 */
	@Override
	protected final void refreshBeanFactory() throws BeansException {
		//在这里,如果创建了BeanFactory就销毁并关闭BeanFactory
		if (hasBeanFactory()) {
			destroyBeans();
			closeBeanFactory();
		}
		try {
			//这里是创建并设置持有的DefaultListableBeanFactory的地方同时调用loadBeanDefinition状态bean定义
			DefaultListableBeanFactory beanFactory =createBeanFactory();
			beanFactory.setSerializationId(getId());
			customizeBeanFactory(beanFactory);
			loadBeanDefinitions(beanFactory);
			synchronized (this.beanFactoryMonitor) {
				this.beanFactory = beanFactory;
			}
		}
		catch (IOException ex) {
			throw new ApplicationContextException("I/O error parsing bean definition source for " + getDisplayName(), ex);
		}
	}

上面createBeanFactory
/**
	 * 这里是创建DefaultListableBeanFactory 地地方,用getInternalParentBeanFactory()的具体实现可以参看
	 * @see AbstractApplicationContext#getInternalParentBeanFactory() 的实现,会根据已有的双亲IOC容器
	 * 信息生成DefaultListableBeanFactory的双亲Ioc容器
	 * @return
	 */
	protected DefaultListableBeanFactory createBeanFactory() {
		return new DefaultListableBeanFactory(getInternalParentBeanFactory());
	}

loadBeanDefinitions 是个抽象方法,具体实现交给子类完成
	/**
	 * BeanDefinitionReader载入Bean定义,具体实现委托子类完成
	 * @param beanFactory
	 * @throws BeansException
	 * @throws IOException
	 */
	protected abstract void loadBeanDefinitions(DefaultListableBeanFactory beanFactory)
			throws BeansException, IOException;

具体子类
public int loadBeanDefinitions(String location, Set<Resource> actualResources) throws BeanDefinitionStoreException {
		//这里取得ResourceLoader用的是DefaultResourceLoader
		ResourceLoader resourceLoader = getResourceLoader();
		if (resourceLoader == null) {
			throw new BeanDefinitionStoreException(
					"Cannot import bean definitions from location [" + location + "]: no ResourceLoader available");
		}

		//这里对Resource的路径进行解析,这些Resource指向BeanDefinition信息
		if (resourceLoader instanceof ResourcePatternResolver) {
			// Resource pattern matching available.
			try {

				Resource[] resources = ((ResourcePatternResolver) resourceLoader).getResources(location);
				int loadCount = loadBeanDefinitions(resources);
				if (actualResources != null) {
					for (Resource resource : resources) {
						actualResources.add(resource);
					}
				}
				if (logger.isDebugEnabled()) {
					logger.debug("Loaded " + loadCount + " bean definitions from location pattern [" + location + "]");
				}
				return loadCount;
			}
			catch (IOException ex) {
				throw new BeanDefinitionStoreException(
						"Could not resolve bean definition resource pattern [" + location + "]", ex);
			}
		}
		else {
			// Can only load single resources by absolute URL.
			Resource resource = resourceLoader.getResource(location);
			int loadCount = loadBeanDefinitions(resource);
			if (actualResources != null) {
				actualResources.add(resource);
			}
			if (logger.isDebugEnabled()) {
				logger.debug("Loaded " + loadCount + " bean definitions from location [" + location + "]");
			}
			return loadCount;
		}
	}

再来看看getResource,他的具体实现在DefaultResourceLoader里
public Resource getResource(String location) {
		Assert.notNull(location, "Location must not be null");
		//处理带有classpath标示的Resource
		if (location.startsWith(CLASSPATH_URL_PREFIX)) {
			return new ClassPathResource(location.substring(CLASSPATH_URL_PREFIX.length()), getClassLoader());
		}
		else {
			try {
				// Try to parse the location as a URL...
				//处理URL标示的Resource
				URL url = new URL(location);
				return new UrlResource(url);
			}
			catch (MalformedURLException ex) {
				// No URL -> resolve as resource path.
				//如果既不是classpath的Resource 又不是url的Resource,
				//重新交给getResourceByPath,这个方法是一个protected方法,默认实现是得到
				//一个ClassPathContextResource,这个方法常常会用子类实现
				return getResourceByPath(location);
			}
		}
	}

猜你喜欢

转载自lee3836.iteye.com/blog/2263439