`
lee3836
  • 浏览: 68281 次
  • 性别: Icon_minigender_1
  • 来自: 北京
社区版块
存档分类
最新评论

【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);
			}
		}
	}
分享到:
评论

相关推荐

    Spring IoC加载流程讲解

    在 obtainFreshBeanFactory() 方法中,我们调用子类 AbstractRefreshableApplicationContext 的 refreshBeanFactory() 方法,该方法又调用子类 AbstractXmlApplicationContext 的 loadBeanDefinitions...

    18 Spring IoC容器如何读取应用外部的xml,txt,图形或者属性文件?慕课专栏(1)1

    `AbstractBeanDefinitionReader`类是用于读取和解析XML文件的关键组件,它负责将XML配置转换为Spring可以理解的Bean定义。 值得注意的是,Spring还支持其他类型的外部配置,例如属性文件。我们可以使用`...

    Spring完美教程

    ### Spring完美教程解析 #### 一、Spring框架简介 Spring框架是Java开发中最常用的企业级应用框架之一,它提供了一种轻量级的容器管理方式,使得开发者可以更轻松地进行依赖注入(Dependency Injection, DI)和...

    Spring源码分析

    本篇文章将对Spring的启动过程以及核心组件进行详细的解析。 #### 二、核心接口与类介绍 **1. BeanFactory** - **BeanFactory** 是Spring中最基础的接口,它是工厂模式的一个实现,用于创建和管理Bean对象。...

    spring完美教程

    - `ClassPathXmlApplicationContext`是Spring提供的一个实现,用于从类路径下的XML配置文件创建ApplicationContext。它是`AbstractApplicationContext`的子类,提供了加载和刷新配置的能力。 - `...

    SPRING API 2.0.CHM

    AbstractRefreshableApplicationContext AbstractRefreshablePortletApplicationContext AbstractRefreshableTargetSource AbstractRefreshableWebApplicationContext AbstractRegexpMethodPointcut ...

    ApplicationContext容器的uml类图

    ### ApplicationContext容器概述与UML类图解析 #### 一、ApplicationContext接口简介 `ApplicationContext`接口在Spring框架中扮演着至关重要的角色,它是Spring容器的一种高级形式,提供了比基础的`BeanFactory`...

Global site tag (gtag.js) - Google Analytics