freezeConfiguration Spring冻结的解析

	/**
	 * 冻结所有bean定义,表示已注册的bean定义将不会被进一步修改或后处理。
	 * <p>This allows the factory to aggressively cache bean definition metadata.
	 */
	void freezeConfiguration();
	@Override
	public void freezeConfiguration() {
		this.configurationFrozen = true;
		this.frozenBeanDefinitionNames = StringUtils.toStringArray(this.beanDefinitionNames);
	}

前面几篇文章分析代码里面都动不动会提到是否冻结

boolean isConfigurationFrozen();

	@Override
	public boolean isConfigurationFrozen() {
		return this.configurationFrozen;
	}

	private volatile boolean configurationFrozen;

这两个方法都是beanFactoryPostProcessor的扩展点的方法。

也就是这个属性,是否为true,true就是表示已经被冻结了,也就是调用这个freezeConfiguration可以将其冻结。

那么什么是冻结呢?冻结啥呢?冻结有什么用呢?咱们接着看

所谓的冻结就是spring不会标识一个bd已经过期;也就是你如果对一个bd更改了属性(在冻结之后);不会被合并了;因为你修改了bd,但是spring不会觉得这个bd已经过期(判断已经冻结,不会合并);故而修改的不会生效;

 

可以看看Spring会在哪调用这个冻结

finishBeanFactoryInitialization(beanFactory);

真正被调用是在refresh()的这个方法里

	protected void finishBeanFactoryInitialization(ConfigurableListableBeanFactory beanFactory) {
		// Initialize conversion service for this context.
		if (beanFactory.containsBean(CONVERSION_SERVICE_BEAN_NAME) &&
				beanFactory.isTypeMatch(CONVERSION_SERVICE_BEAN_NAME, ConversionService.class)) {
			beanFactory.setConversionService(
					beanFactory.getBean(CONVERSION_SERVICE_BEAN_NAME, ConversionService.class));
		}

		// Register a default embedded value resolver if no BeanFactoryPostProcessor
		// (such as a PropertySourcesPlaceholderConfigurer bean) registered any before:
		// at this point, primarily for resolution in annotation attribute values.
		if (!beanFactory.hasEmbeddedValueResolver()) {
			beanFactory.addEmbeddedValueResolver(strVal -> getEnvironment().resolvePlaceholders(strVal));
		}

		// Initialize LoadTimeWeaverAware beans early to allow for registering their transformers early.
		String[] weaverAwareNames = beanFactory.getBeanNamesForType(LoadTimeWeaverAware.class, false, false);
		for (String weaverAwareName : weaverAwareNames) {
			getBean(weaverAwareName);
		}

		// Stop using the temporary ClassLoader for type matching.
		beanFactory.setTempClassLoader(null);

		//冻结所有的beanDefinition
		// Allow for caching all bean definition metadata, not expecting further changes.
		beanFactory.freezeConfiguration();

		//实例化所有的单例bean
		// Instantiate all remaining (non-lazy-init) singletons.
		beanFactory.preInstantiateSingletons();
	}

前面的代码先不管,就看后面两个,可以看到在这里面,是先进行了冻结,再调用下面的函数,实例化所有的单例bean。

那么为什么要冻结呢?

这个就要看我前面写的文章了,在很多地方都有提到这个冻结的判断,

@Override
public void clearMetadataCache() {
   //表示mergedbdmap当中的bd过期了   没有冻结
   super.clearMetadataCache();
   this.mergedBeanDefinitionHolders.clear();
   clearByTypeCache();
}

这个方法也是beanFactoryPOSTProcessor的扩展点方法

这个方法里面的clearMetadataCache

public void clearMetadataCache() {
		this.mergedBeanDefinitions.forEach((beanName, bd) -> {
			//如果被冻结则不会进if,表示不会重写merged
			//会调用子类的这个方法
			if (!isBeanEligibleForMetadataCaching(beanName)) {
				//改这个标识,默认为false
				bd.stale = true;
			}
		});
	}

	protected boolean isBeanEligibleForMetadataCaching(String beanName) {
		//判断是否被冻结或者这个bean是否已经开始被创建了。
		return (this.configurationFrozen || super.isBeanEligibleForMetadataCaching(beanName));
	}

这个就是通过是否已经冻结了来判断,如果被冻结了,就不会进入if去改bd的stale,这个东西,又和merge合并有关系。

所以前面写的文章要连起来看代码多想想,很多都是连在一起的

那么这个stale可以在我写的mergedBeanDefinition中会有发现,

在这个方法中会有判断,判断bd的stale,如果为false,则不用合并直接返回bd。

所以可以明白了吧,这个stale就是一个标识,标识此bd是否需要再合并。

而冻结,就能够让bd的stale为false,也就是不用再合并。

合并这个可以看mergedBeanDefinition文章。你会发现,其实在Spring里面,有多个bdmap。而为啥spring要这么搞,我现在也不太清楚,可能跟业务逻辑有关系吧。

 

  • 0
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值