3.3-1、Spring源码学习:prepareBeanFactory(beanFactory);

本文深入探讨Spring框架中BeanFactory的初始化过程,包括类加载器、SpEL解析器配置、属性编辑器设置、特殊接口自动注入排除及指定类型注入。详解AbstractApplicationContext.prepareBeanFactory方法,演示如何将环境相关对象注册为单例。

摘要生成于 C知道 ,由 DeepSeek-R1 满血版支持, 前往体验 >

前言

世界观第一,体能第二,技术第三

承上启下

本文就Spring 源码中 refresh()方法中的 prepareBeanFactory(beanFactory);进行学习和解读.
相较而言,本方法内部的逻辑不算复杂。
本方法用于设置 beanFactory 的类加器、SpEL解析器、bean的属性编辑器、特殊接口的免自动注入和特殊类型的指定注入.对环境相关的对象 environment、systemProperties、systemEnvironment 设置为 beanFactory 单例.

AbstractApplicationContext.prepareBeanFactory(ConfigurableListableBeanFactory beanFactory)

org.springframework.context.support.AbstractApplicationContext.prepareBeanFactory(ConfigurableListableBeanFactory beanFactory)

本方法内部没有太多复杂的逻辑,主要做了一些准备工作,具体看注释吧

/**
	 * Configure the factory's standard context characteristics,
	 * such as the context's ClassLoader and post-processors.
	 * @param beanFactory the BeanFactory to configure
	 */
	protected void prepareBeanFactory(ConfigurableListableBeanFactory beanFactory) {
		//为内部 bean factory 指定使用 上下文类加载器
		// Tell the internal bean factory to use the context's class loader etc.
		beanFactory.setBeanClassLoader(getClassLoader());
		
		//指定 bean 表达解析器为 StandardBeanExpressionResolver,用于解析 Spring EL 表达式,前缀为 "#{",后缀为"}"
		// 用法,比如Java代码中 @Value("#{表达式}") 
		// 用法,比如xml文档中 <property name="arg" value="#{表达式}">
		beanFactory.setBeanExpressionResolver(new StandardBeanExpressionResolver(beanFactory.getBeanClassLoader()));
		
		//设置 bean 属性编辑器,便于对bean的属性进行编辑
		beanFactory.addPropertyEditorRegistrar(new ResourceEditorRegistrar(this, getEnvironment()));

		// Configure the bean factory with context callbacks.
		beanFactory.addBeanPostProcessor(new ApplicationContextAwareProcessor(this));
		
		//ignoreDependencyInterface 表示该接口不使用自动注入 
		//ResourceLoaderAware、ApplicationEventPublisherAware、
		//MessageSourceAware、ApplicationContextAware、EnvironmentAware
		beanFactory.ignoreDependencyInterface(ResourceLoaderAware.class);
		beanFactory.ignoreDependencyInterface(ApplicationEventPublisherAware.class);
		beanFactory.ignoreDependencyInterface(MessageSourceAware.class);
		beanFactory.ignoreDependencyInterface(ApplicationContextAware.class);
		beanFactory.ignoreDependencyInterface(EnvironmentAware.class);

		// registerResolvableDependency 表示该类型使用指定的对象注入
		// 比如 BeanFactory.class 就注入 beanFactory 对象
		//ResourceLoader.class、ApplicationEventPublisher.class、ApplicationContext.class 就注入 this-调用类自身
		beanFactory.registerResolvableDependency(BeanFactory.class, beanFactory);
		beanFactory.registerResolvableDependency(ResourceLoader.class, this);
		beanFactory.registerResolvableDependency(ApplicationEventPublisher.class, this);
		beanFactory.registerResolvableDependency(ApplicationContext.class, this);

		//默认不会进入内部逻辑
		//增加了对AspectJ的支持
		//spring的loadTimeWeaver主要是通过 instrumentation 的动态字节码增强在装载期注入依赖
		if (beanFactory.containsBean(LOAD_TIME_WEAVER_BEAN_NAME)) {
			beanFactory.addBeanPostProcessor(new LoadTimeWeaverAwareProcessor(beanFactory));
			// Set a temporary ClassLoader for type matching.
			beanFactory.setTempClassLoader(new ContextTypeMatchClassLoader(beanFactory.getBeanClassLoader()));
		}

		// 下面是三个为 beanFactory 添加单例的代码,后面会单独讲解.
		// 注册默认的环境相关 beans.
		// beanName 为 environment
		if (!beanFactory.containsLocalBean(ENVIRONMENT_BEAN_NAME)) {
			beanFactory.registerSingleton(ENVIRONMENT_BEAN_NAME, getEnvironment());
		}
		//beanName 为 systemProperties
		if (!beanFactory.containsLocalBean(SYSTEM_PROPERTIES_BEAN_NAME)) {
			beanFactory.registerSingleton(SYSTEM_PROPERTIES_BEAN_NAME, getEnvironment().getSystemProperties());
		}
		//beanName 为 systemEnvironment
		if (!beanFactory.containsLocalBean(SYSTEM_ENVIRONMENT_BEAN_NAME)) {
			beanFactory.registerSingleton(SYSTEM_ENVIRONMENT_BEAN_NAME, getEnvironment().getSystemEnvironment());
		}
	}
beanFactory 添加单例 bean 的过程

上面代码片段中,有将三个和上下文环境相关的对象添加为 beanFactory 单例 bean的逻辑.
beanFactory.registerSingleton(ENVIRONMENT_BEAN_NAME, getEnvironment());为例.

DefaultListableBeanFactory.registerSingleton(String beanName, Object singletonObject)

org.springframework.beans.factory.support.DefaultListableBeanFactory.registerSingleton(String beanName, Object singletonObject)

@Override
public void registerSingleton(String beanName, Object singletonObject) throws IllegalStateException {
	//关键的一行
	super.registerSingleton(beanName, singletonObject);
	
	//如果尚未开始创建
	if (hasBeanCreationStarted()) {
		// Cannot modify startup-time collection elements anymore (for stable iteration)
		synchronized (this.beanDefinitionMap) {
			if (!this.beanDefinitionMap.containsKey(beanName)) {
				Set<String> updatedSingletons = new LinkedHashSet<String>(this.manualSingletonNames.size() + 1);
				updatedSingletons.addAll(this.manualSingletonNames);
				updatedSingletons.add(beanName);
				this.manualSingletonNames = updatedSingletons;
			}
		}
	}
	else {
		// 依旧在启动阶段
		//如果 beanDefinitionMap 不包含 beanName,则将该beanName添加到  manualSingletonNames(手动单例名字Set集合中)
		if (!this.beanDefinitionMap.containsKey(beanName)) {
			this.manualSingletonNames.add(beanName);
		}
	}

	clearByTypeCache();
}
DefaultSingletonBeanRegistry.registerSingleton(String beanName, Object singletonObject)

org.springframework.beans.factory.support.DefaultSingletonBeanRegistry.registerSingleton(String beanName, Object singletonObject)

@Override
public void registerSingleton(String beanName, Object singletonObject) throws IllegalStateException {
	Assert.notNull(beanName, "'beanName' must not be null");
	synchronized (this.singletonObjects) {
		//	如果单例对象已经存在了,则抛出异常
		Object oldObject = this.singletonObjects.get(beanName);
		if (oldObject != null) {
			throw new IllegalStateException("Could not register object [" + singletonObject +
					"] under bean name '" + beanName + "': there is already object [" + oldObject + "] bound");
		}
		//这是关键一行
		addSingleton(beanName, singletonObject);
	}
}
DefaultSingletonBeanRegistry.addSingleton(String beanName, Object singletonObject)

org.springframework.beans.factory.support.DefaultSingletonBeanRegistry.addSingleton(String beanName, Object singletonObject)

protected void addSingleton(String beanName, Object singletonObject) {
	synchronized (this.singletonObjects) {
		//下面几个都是 Map 对象
		//单例对象
		this.singletonObjects.put(beanName, (singletonObject != null ? singletonObject : NULL_OBJECT));
		//单例工厂
		this.singletonFactories.remove(beanName);
		//早期的单例对象
		this.earlySingletonObjects.remove(beanName);
		//已被注册的单例
		this.registeredSingletons.add(beanName);
	}
}
判断是否开始创建bean:hasBeanCreationStarted()
protected boolean hasBeanCreationStarted() {
//如果非空,表示已经开始创建,否则表示尚未开始创建
		return !this.alreadyCreated.isEmpty();
	}
清除缓存: clearByTypeCache()

清除缓存,防止之前到调用到影响

private void clearByTypeCache() {
		this.allBeanNamesByType.clear();
		this.singletonBeanNamesByType.clear();
	}

参考资料

[1]、https://yq.aliyun.com/articles/666890
[2]、https://blog.youkuaiyun.com/cuichunchi/article/details/90407632

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值