Spring源码 - 容器刷新#prepareBeanFactory()

Spring源码 - 容器刷新#prepareBeanFactory()

Spring版本:Spring 5.3.13-release


# 1、prepareBeanFactory()BeanFactory进行属性填充

prepareBeanFactory()Spring容器刷新的第三个方法,其字面意思为获取新鲜的Bean工厂。为AbstractApplicationContext中的BeanFactory填充属性。为后续的工作提供帮助。

AbstractApplicationContext#prepareBeanFactory()代码:

	/**
	 * 配置工厂的标准上下文特征, 比如上下文类加载器和后置处理器
	 *
	 * 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) {
		// Tell the internal bean factory to use the context's class loader etc.
		// 设置当前 beanFactory 的 classLoader 为当前 context 的 classLoader
		beanFactory.setBeanClassLoader(getClassLoader());
		if (!shouldIgnoreSpel) {
			// 设置 beanFactory 的表达式语言处理器(即 spel spring expression language 在 Spring3.x 中增加的表达式语言支持)。
			beanFactory.setBeanExpressionResolver(new StandardBeanExpressionResolver(beanFactory.getBeanClassLoader()));
		}
		// 为 beanFactory 增加一个默认的 propertyEditor, 这个主要是针对 bean 的属性等设置管理的一个工具
		beanFactory.addPropertyEditorRegistrar(new ResourceEditorRegistrar(this, getEnvironment()));

		// Configure the bean factory with context callbacks.
		// 添加 BeanPostProcessor。ApplicationContextAwareProcessor 类用来完成某些 Aware 对象的注入
		beanFactory.addBeanPostProcessor(new ApplicationContextAwareProcessor(this));

		// 设置要忽略自动装配的接口
		beanFactory.ignoreDependencyInterface(EnvironmentAware.class);
		beanFactory.ignoreDependencyInterface(EmbeddedValueResolverAware.class);
		beanFactory.ignoreDependencyInterface(ResourceLoaderAware.class);
		beanFactory.ignoreDependencyInterface(ApplicationEventPublisherAware.class);
		beanFactory.ignoreDependencyInterface(MessageSourceAware.class);
		beanFactory.ignoreDependencyInterface(ApplicationContextAware.class);
		beanFactory.ignoreDependencyInterface(ApplicationStartupAware.class);

		// BeanFactory interface not registered as resolvable type in a plain factory.
		// MessageSource registered (and found for autowiring) as a bean.
		// 设置几个自动装配的特殊规则, 当在进行 IOC 容器初始化过程中如果有多个实现, 那么就使用指定的对象进行依赖注入
		beanFactory.registerResolvableDependency(BeanFactory.class, beanFactory);
		beanFactory.registerResolvableDependency(ResourceLoader.class, this);
		beanFactory.registerResolvableDependency(ApplicationEventPublisher.class, this);
		beanFactory.registerResolvableDependency(ApplicationContext.class, this);

		// Register early post-processor for detecting inner beans as ApplicationListeners.
		// 注册 BeanPostProcessor
		beanFactory.addBeanPostProcessor(new ApplicationListenerDetector(this));

		// Detect a LoadTimeWeaver and prepare for weaving, if found.
		// 通过 Aspect J 的类加载器织入
		if (!NativeDetector.inNativeImage() && 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()));
		}

		// Register default environment beans.
		// 注册默认的系统环境 Bean (单例)到一级缓存中
		if (!beanFactory.containsLocalBean(ENVIRONMENT_BEAN_NAME)) {
			beanFactory.registerSingleton(ENVIRONMENT_BEAN_NAME, getEnvironment());
		}
		if (!beanFactory.containsLocalBean(SYSTEM_PROPERTIES_BEAN_NAME)) {
			beanFactory.registerSingleton(SYSTEM_PROPERTIES_BEAN_NAME, getEnvironment().getSystemProperties());
		}
		if (!beanFactory.containsLocalBean(SYSTEM_ENVIRONMENT_BEAN_NAME)) {
			beanFactory.registerSingleton(SYSTEM_ENVIRONMENT_BEAN_NAME, getEnvironment().getSystemEnvironment());
		}
		if (!beanFactory.containsLocalBean(APPLICATION_STARTUP_BEAN_NAME)) {
			beanFactory.registerSingleton(APPLICATION_STARTUP_BEAN_NAME, getApplicationStartup());
		}
	}

这里代码很清晰,为BeanFactory设置属性是忽略那7个指定的*Aware接口, 因为这些接口的实现是由容器通过set方法进行注入的。

Java中织入分为三种方式:

  • 编译器织入:在Java编译器采用特殊的编译器, 将切面织入到Java类中
  • 类加载器织入:通过特殊的类加载器, 在字节码加载到JVM中时, 织入切面
  • 运行期织入:采用CGLIBJDK进行切面的织入

同时增加对Aspect J的支持,Aspect J提供了两种织入方式:

  • 第一种是通过编译器织入,将使用Aspect J语言编写的切面类织入到 Java 类中

  • 第二种是通过类加载器织入,就是上面的loadTimeWeaver (LOAD_TIME_WEAVER_BEAN_NAME)

GitHub源码地址https://github.com/kapbc/kapcb-spring-source/tree/master/Spring-Framework-v5.3.13

备注:此文为笔者学习Spring源码的笔记,鉴于本人技术有限,文中难免出现一些错误,感谢大家批评指正。

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值