3.2-1、Spring源码学习:ConfigurableListableBeanFactory beanFactory = obtainFreshBeanFactory();

前言

体能状态先于精神状态,习惯先于决心,聚焦先于喜好。

承上启下

本方法用于将配置文件中的bean加载到 beanDefination 中,然后将beanDefination 放入到 beanFactory,但是需要注意到是,只是加载了 bean到定义信息,还没有进行注入、实例化等工作.

AbstractApplicationContext.obtainFreshBeanFactory(

org.springframework.context.support.AbstractApplicationContext.obtainFreshBeanFactory(
通知子类 refresh 内部的 bean factory

/**
	 * @return the fresh BeanFactory instance
	 * @see #refreshBeanFactory()
	 * @see #getBeanFactory()
	 */
	protected ConfigurableListableBeanFactory obtainFreshBeanFactory() {
	    //创建一个 beanFactory 对象
		refreshBeanFactory();
		//bean配置文件加载和解析工作已经完成,这里只是简单的验证一下非空,如果非空则返回已加载完毕的值
		ConfigurableListableBeanFactory beanFactory = getBeanFactory();
		if (logger.isDebugEnabled()) {
			logger.debug("Bean factory for " + getDisplayName() + ": " + beanFactory);
		}
		return beanFactory;
	}

AbstractRefreshableApplicationContext.refreshBeanFactory(

org.springframework.context.support.AbstractRefreshableApplicationContext.refreshBeanFactory(
用于创建一个BeanFactory(DefaultListableBeanFactory ),为之后使用,如果之前的操作存在这么个 BeanFactory,则先将之前的 BeanFactory 进行销毁。
新创建的 BeanFactory 将服务于 下一阶段 上下文的声明周期

@Override
	protected final void refreshBeanFactory() throws BeansException {
		// 如果 beanFactory已存在,则销毁,这里的操作都是用了 对象锁进行同步
		if (hasBeanFactory()) {
			destroyBeans();
			closeBeanFactory();
		}
		try {
		    //创建 BeanFactory,内部会检测父工厂,默认父工厂为null
			DefaultListableBeanFactory beanFactory = createBeanFactory();
			//设置序列化id,以 webApplicationContext 的id相同
			beanFactory.setSerializationId(getId());
			//更新 allowBeanDefinitionOverriding 和 allowCircularReferences 的值,默认这段代码没用,不会修改默认值,除非你beanFactory.set*Name 修改了值
			customizeBeanFactory(beanFactory);
			//为 beanFactory 记载 bean定义文件 
			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,这里面有对 DefaultListableBeanFactory 和其父类的基本常量的介绍。
比如默认cglib动态代理、允许覆盖同名bean、允许循环依赖、允许立即加载需要的类、不允许使用原始类型注入作为解决循环依赖的方法等等。
再一个需要忽略依赖和注入的接口,默认只有 BeanFactory interface,但是在 DefaultListableBeanFactory 中其实增加了 BeanNameAware、BeanFactoryAware和BeanClassLoaderAware 三个接口要被忽略

	protected DefaultListableBeanFactory createBeanFactory() {
	//getInternalParentBeanFactory() 返参默认为null,即没有父工厂
		return new DefaultListableBeanFactory(getInternalParentBeanFactory());
	}
loadBeanDefinitions(beanFactory);

org.springframework.web.context.support.XmlWebApplicationContext.loadBeanDefinitions(

这个步骤比较关键,用于加载定义 bean 的配置文件,一般我们会定义一个或者多个 applicationContext.xml,当然,这个功能最终是体现在 loadBeanDefinitions(beanDefinitionReader); 中的

@Override
	protected void loadBeanDefinitions(DefaultListableBeanFactory beanFactory) throws BeansException, IOException {
		//为 beanFactory 创建一个 XmlBeanDefinitionReader 对象
		XmlBeanDefinitionReader beanDefinitionReader = new XmlBeanDefinitionReader(beanFactory);

        // 使用上下文资源加载 变量参数,配置 bean 定义的reader  
		// Configure the bean definition reader with this context's
		// resource loading environment.
		beanDefinitionReader.setEnvironment(getEnvironment());
		beanDefinitionReader.setResourceLoader(this);
		beanDefinitionReader.setEntityResolver(new ResourceEntityResolver(this));

		// 允许一个子列提供自定义的 reader对象的实现,然后再开始具体bean 定义加载过程
		//默认这是一个空方法
		initBeanDefinitionReader(beanDefinitionReader);
		//正式加载
		loadBeanDefinitions(beanDefinitionReader);
	}
XmlWebApplicationContext.loadBeanDefinitions(

org.springframework.web.context.support.XmlWebApplicationContext.loadBeanDefinitions(

使用 XmlBeanDefinitionReader 加载 bean定义文件。
bean factory的声明周期由 refreshBeanFactory 方法控制,本方法仅用于加载或者注册 bean定义文件。
内部委托 ResourcePatternResolver 将本地文件进行解析为资源实例。对于这部分逻辑的解析再写一篇文章 reader.loadBeanDefinitions(configLocation);

	
	 * <p>Delegates to a ResourcePatternResolver for resolving location patterns
	 * into Resource instances.
protected void loadBeanDefinitions(XmlBeanDefinitionReader reader) throws IOException {
        //考虑通配符的情况,对文件路径进行转化
		String[] configLocations = getConfigLocations();
		if (configLocations != null) {
			for (String configLocation : configLocations) {
				//内部委托 ResourcePatternResolver  将本地文件进行解析为资源实例
				reader.loadBeanDefinitions(configLocation);
			}
		}
	}

AbstractRefreshableApplicationContext.getBeanFactory()

org.springframework.context.support.AbstractRefreshableApplicationContext.getBeanFactory()

这个方法没有特别复杂的逻辑,只是判断一下 beanFactory 是否存在

@Override
	public final ConfigurableListableBeanFactory getBeanFactory() {
		synchronized (this.beanFactoryMonitor) {
			if (this.beanFactory == null) {
				throw new IllegalStateException("BeanFactory not initialized or already closed - " +
						"call 'refresh' before accessing beans via the ApplicationContext");
			}
			return this.beanFactory;
		}
	}
發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章