prepareBeanFactory(beanFactory) 方法源码详解

发布时间:2026/10/21 4:25:28
prepareBeanFactory(beanFactory) 方法源码详解 prepareBeanFactory(beanFactory)是 Spring 容器刷新refresh过程中的一个关键步骤位于AbstractApplicationContext类中。它在refresh()方法的obtainFreshBeanFactory()之后、postProcessBeanFactory(beanFactory)之前被调用主要用于对刚刚创建好的ConfigurableListableBeanFactory进行标准化的上下文配置为后续的 Bean 实例化、依赖注入等做好准备。方法源码基于 Spring 5.3.xprotected void prepareBeanFactory(ConfigurableListableBeanFactory beanFactory) { // 设置 BeanFactory 的类加载器为当前上下文的类加载器通常为 AppClassLoader beanFactory.setBeanClassLoader(getClassLoader()); // 设置 Bean 表达式解析器用于解析 Bean 定义中的 #{...} 表达式 beanFactory.setBeanExpressionResolver(new StandardBeanExpressionResolver(beanFactory.getBeanClassLoader())); // 添加属性编辑器注册器用于属性转换如 Date、Currency 等 beanFactory.addPropertyEditorRegistrar(new ResourceEditorRegistrar(this, getEnvironment())); // 添加 ApplicationContextAwareProcessor处理实现了 Aware 接口的 Bean // 让这些 Bean 能够感知到 ApplicationContext 及相关资源 beanFactory.addBeanPostProcessor(new ApplicationContextAwareProcessor(this)); // 忽略以下接口的自动装配这些接口由 Aware 回调或框架内部处理 beanFactory.ignoreDependencyInterface(EnvironmentAware.class); beanFactory.ignoreDependencyInterface(EmbeddedValueResolverAware.class); beanFactory.ignoreDependencyInterface(ResourceLoaderAware.class); beanFactory.ignoreDependencyInterface(ApplicationEventPublisherAware.class); beanFactory.ignoreDependencyInterface(MessageSourceAware.class); beanFactory.ignoreDependencyInterface(ApplicationContextAware.class); // 注册特殊的依赖类型当注入这些类型时自动装配对应的 Bean // 例如注入 BeanFactory 时直接获得当前 BeanFactory 实例 beanFactory.registerResolvableDependency(BeanFactory.class, beanFactory); beanFactory.registerResolvableDependency(ResourceLoader.class, this); beanFactory.registerResolvableDependency(ApplicationEventPublisher.class, this); beanFactory.registerResolvableDependency(ApplicationContext.class, this); // 添加 ApplicationListenerDetector用于检测实现了 ApplicationListener 接口的 Bean // 并自动将其添加到事件监听器列表中 beanFactory.addBeanPostProcessor(new ApplicationListenerDetector(this)); // 如果 BeanFactory 中包含 loadTimeWeaver Bean则添加一个 BeanPostProcessor // 用于 AspectJ 加载时织入Load-Time Weaving if (beanFactory.containsBean(LOAD_TIME_WEAVER_BEAN_NAME)) { beanFactory.addBeanPostProcessor(new LoadTimeWeaverAwareProcessor(beanFactory)); // 设置临时类加载器用于类型匹配 beanFactory.setTempClassLoader(new ContextTypeMatchClassLoader(beanFactory.getBeanClassLoader())); } // 注册默认的环境 Bean单例 // 这些 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()); } }逐行详解1. 设置类加载器beanFactory.setBeanClassLoader(getClassLoader());作用将 BeanFactory 使用的类加载器设置为当前ApplicationContext的类加载器。默认情况下getClassLoader()返回线程上下文类加载器若不存在则使用当前类的类加载器。这确保 Bean 的加载与上下文使用相同的类加载器避免 ClassCastException。2. 设置 Bean 表达式解析器beanFactory.setBeanExpressionResolver(new StandardBeanExpressionResolver(beanFactory.getBeanClassLoader()));作用添加StandardBeanExpressionResolver使得在 Bean 定义中可以使用 SpEL 表达式#{...}。例如property namemax value#{2 * 5}/或Value(#{systemProperties[user.name]})。3. 添加属性编辑器注册器beanFactory.addPropertyEditorRegistrar(new ResourceEditorRegistrar(this, getEnvironment()));作用注册ResourceEditorRegistrar它会在需要时将字符串转换为 Spring 资源类型如Resource、InputStream等并利用Environment解析占位符${...}。这样可以在属性注入时自动完成转换。4. 添加ApplicationContextAwareProcessorbeanFactory.addBeanPostProcessor(new ApplicationContextAwareProcessor(this));作用这是一个BeanPostProcessor负责处理实现了Aware接口的 Bean如ApplicationContextAware、EnvironmentAware等。当 Bean 实例化后该处理器会调用相应的setXxx方法将上下文资源注入到 Bean 中。5. 忽略特定依赖接口的自动装配beanFactory.ignoreDependencyInterface(EnvironmentAware.class); beanFactory.ignoreDependencyInterface(EmbeddedValueResolverAware.class); // ... 其他 Aware 接口作用这些接口用于通过Aware回调注入依赖而不是通过自动装配如Autowired。忽略它们可以防止 Spring 在自动装配时尝试解析这些类型的依赖因为它们的注入已经由ApplicationContextAwareProcessor处理。例如EnvironmentAware的注入由ApplicationContextAwareProcessor完成自动装配应忽略它。6. 注册可解析的依赖类型beanFactory.registerResolvableDependency(BeanFactory.class, beanFactory); beanFactory.registerResolvableDependency(ResourceLoader.class, this); // ... 其他作用当依赖注入的目标类型是BeanFactory、ResourceLoader、ApplicationEventPublisher、ApplicationContext时直接使用当前上下文中的对应实例进行注入。例如在 Bean 中Autowired一个ApplicationContext字段Spring 就会注入当前ApplicationContext实例。7. 添加ApplicationListenerDetectorbeanFactory.addBeanPostProcessor(new ApplicationListenerDetector(this));作用该BeanPostProcessor检测 Bean 是否实现了ApplicationListener接口。如果是则在 Bean 初始化完成后自动将其添加到上下文的事件监听器列表中。它也负责在 Bean 被销毁时移除监听器。8. 处理加载时织入Load-Time Weavingif (beanFactory.containsBean(LOAD_TIME_WEAVER_BEAN_NAME)) { beanFactory.addBeanPostProcessor(new LoadTimeWeaverAwareProcessor(beanFactory)); beanFactory.setTempClassLoader(new ContextTypeMatchClassLoader(beanFactory.getBeanClassLoader())); }作用如果存在名为 loadTimeWeaver 的 Bean说明启用了 AspectJ 加载时织入。此时添加一个LoadTimeWeaverAwareProcessor使需要织入的 Bean 能够获取到LoadTimeWeaver同时设置临时类加载器ContextTypeMatchClassLoader用于在类型匹配时支持织入后的类。9. 注册默认的环境单例 Beanif (!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()); }作用将Environment、系统属性Properties、系统环境变量Map作为单例 Bean 注册到容器中。这样用户可以通过Autowired或Resource直接注入这些对象方便获取环境信息。containsLocalBean检查是为了避免用户自定义的同名 Bean 被覆盖。总结prepareBeanFactory方法是 Spring 容器启动过程中的一个“装配”步骤它赋予 BeanFactory 与当前应用上下文相关的标准能力类加载机制确保类加载一致表达式支持启用 SpEL类型转换注册属性编辑器Aware 接口处理自动注入上下文资源依赖解析处理特殊类型的注入事件监听自动注册监听器环境集成注册环境相关的单例通过这些设置BeanFactory 从一个“原始”的工厂变成了一个与ApplicationContext环境深度整合的容器为后续的 Bean 实例化、属性填充、初始化等阶段打下了坚实的基础。理解这一方法有助于深入把握 Spring 容器的生命周期和扩展点。

关于本文作者

来自尧图内容编辑团队

尧图内容编辑团队 内容团队

尧图内容编辑团队

本文由尧图网络内容编辑团队执笔。团队由资深项目经理、前端工程师与设计师组成,所有内容均来自亲手交付的真实项目,先讲清问题、再给出可落地的解法。尧图深耕北京网站建设十年,服务过京华建材集团、智造科技等各行业客户,把一线经验沉淀为可复用的行业观察。

  • 十年建站经验,覆盖建材、制造、服务、文创等
  • 项目经理把关选题与事实准确性
  • 工程师与设计师联合撰写专业细节
  • 统一编辑规范,保证文风与排版一致
  • 每月复盘转化数据,迭代选题方向

延伸阅读

相关资讯与近期热门内容

深度阅读推荐

建站决策前值得细读的三篇

网站改版的5个关键决策
2024-08-12

网站改版的5个关键决策

什么时候该改版、改到什么程度、如何避免流量掉光,京华建材集团改版复盘给出答案。

获取专属建站方案

看完文章,把您的行业与预算告诉我们,免费获取一份量身定制的官网建设方案与报价。

立即免费咨询