Spring启动流程2--obtainFreshBeanFactory方法

可能已经启动了另外一个Bean工厂,所以需要刷新,先关闭,再启动一个新的Bean工厂;

	protected ConfigurableListableBeanFactory obtainFreshBeanFactory() {
        // 初始化BeanFactory,并进行XML文件读取,并将得到的BeanFactory记录再当前实体的属性中
		refreshBeanFactory();
        // 返回当前实体的BeanFactory属性
		return getBeanFactory();
	}

如果有就删除和关闭

没有就创建,设置Id,自定义BeanFactory

	protected final void refreshBeanFactory() throws BeansException {
		if (hasBeanFactory()) {
			destroyBeans();
			closeBeanFactory();
		}
		try {
			DefaultListableBeanFactory beanFactory = createBeanFactory();
            // 
			beanFactory.setSerializationId(getId());
			customizeBeanFactory(beanFactory);
			loadBeanDefinitions(beanFactory);
			this.beanFactory = beanFactory;
		}
		catch (IOException ex) {
			throw new ApplicationContextException("I/O error parsing bean definition source for " + getDisplayName(), ex);
		}
	}

下面这个方法也是可以扩展的,可以修改相关的属性,通过extents重写这个类,然后super()调用父类的方法就可以了;

allowBeanDefinitionOverriding允许Bean的定义信息覆盖:lookup注解的原理,就是依靠了这个注解,原型Bean,每次获取都获取新的Bean。

allowCircularReferences允许循环引用:是否允许循环引用

	protected void customizeBeanFactory(DefaultListableBeanFactory beanFactory) {
		if (this.allowBeanDefinitionOverriding != null) {
			beanFactory.setAllowBeanDefinitionOverriding(this.allowBeanDefinitionOverriding);
		}
		if (this.allowCircularReferences != null) {
			beanFactory.setAllowCircularReferences(this.allowCircularReferences);
		}
	}

loadBeanDefinitions,第二个重要的代码块

加载Bean的定义信息,将信息存储到工程类中,这里就体现到了设计模式。适配器的设计模式。

package org.springframework.core.Constatnts类,对类文件中的场景进行管理封装成一个实例。
private static final Constants constants = new Constants(XmlBeanDefinitionReader.class);

Spring中的注册接口,声明了接口可以用来注册类型,比如BeanDefinitionRegistry可以用来注册BeanDefinition。

这个Generator实现了接口,实际干活委派给了Utils类。

public class DefaultBeanNameGenerator implements BeanNameGenerator {

	/**
	 * A convenient constant for a default {@code DefaultBeanNameGenerator} instance,
	 * as used for {@link AbstractBeanDefinitionReader} setup.
	 * @since 5.2
	 */
	public static final DefaultBeanNameGenerator INSTANCE = new DefaultBeanNameGenerator();


	@Override
	public String generateBeanName(BeanDefinition definition, BeanDefinitionRegistry registry) {
		return BeanDefinitionReaderUtils.generateBeanName(definition, registry);
	}

}

public class NamedThreadLocal<T> extends ThreadLocal<T> {

   private final String name;


   /**
    * Create a new NamedThreadLocal with the given name.
    * @param name a descriptive name for this ThreadLocal
    */
   public NamedThreadLocal(String name) {
      Assert.hasText(name, "Name must not be empty");
      this.name = name;
   }

   @Override
   public String toString() {
      return this.name;
   }

}

这个StringUtils的方法可以用来使用任意一个分隔符解析分割,很好用。

public static String[] tokenizeToStringArray(@Nullable String str, String delimiters) {
   return tokenizeToStringArray(str, delimiters, true, true);
}

root和generic不是继承的关系 

流式变成,一个断言一个Consumer

private void removeManualSingletonName(String beanName) {
   updateManualSingletonNames(set -> set.remove(beanName), set -> set.contains(beanName));
}

/**
 * Update the factory's internal set of manual singleton names.
 * @param action the modification action
 * @param condition a precondition for the modification action
 * (if this condition does not apply, the action can be skipped)
 */
private void updateManualSingletonNames(Consumer<Set<String>> action, Predicate<Set<String>> condition) {
   if (hasBeanCreationStarted()) {
      // Cannot modify startup-time collection elements anymore (for stable iteration)
      synchronized (this.beanDefinitionMap) {
         if (condition.test(this.manualSingletonNames)) {
            Set<String> updatedSingletons = new LinkedHashSet<>(this.manualSingletonNames);
            action.accept(updatedSingletons);
            this.manualSingletonNames = updatedSingletons;
         }
      }
   }
   else {
      // Still in startup registration phase
      if (condition.test(this.manualSingletonNames)) {
         action.accept(this.manualSingletonNames);
      }
   }
}

总结:

流程十分,非常的繁杂,包括了对文件的解析,总之最后将文件或者注解解析完成后,会放在beanFactory中的两个日期中,一个是Map,key是bean的名字,value是BeanDefinition,另外一个是Set,存储的是beanName,这个其中涉及到了许多的类,组合起来和抽象起来,非常多的分支,很难看明白或者看透彻,这里面每一个类都是可以拿来研究的,比如研究抽象了什么,怎么时候,命名等等。

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值