Spring 源码学习 10:prepareBeanFactory 和 postProcessBeanFactory

简介: 根据 refresh 流程,当 obtainFreshBeanFactory 执行结束后,下一步会执行 prepareBeanFactory ,顾名思义,这个方法主要是准备 BeanFactory,下面一起看一看这部分逻辑。

前言


根据 refresh 流程,当 obtainFreshBeanFactory 执行结束后,下一步会执行 prepareBeanFactory ,顾名思义,这个方法主要是准备 BeanFactory,下面一起看一看这部分逻辑。


prepareBeanFactory

protected void prepareBeanFactory(ConfigurableListableBeanFactory beanFactory) {
    // Tell the internal bean factory to use the context's class loader etc.
    // 设置beanFactory的类加载器
    beanFactory.setBeanClassLoader(getClassLoader());
    // spring.spel.ignore 属性控制是否解析 SpEL 表达式
    if (!shouldIgnoreSpel) {
        beanFactory.setBeanExpressionResolver(new StandardBeanExpressionResolver(beanFactory.getBeanClassLoader()));
    }
    // 设置属性解析器
    beanFactory.addPropertyEditorRegistrar(new ResourceEditorRegistrar(this, getEnvironment()));
    // Configure the bean factory with context callbacks.
    // 添加到后置处理器列表, 新创建的 ApplicationContextAwareProcessor 入参为当前 ApplicationContext
    beanFactory.addBeanPostProcessor(new ApplicationContextAwareProcessor(this));
    // 忽略自动装配
    // 默认情况下 只有BeanFactoryAware 被忽略 要忽略其他类型,需要单独设置
    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(ApplicationStartup.class);
    // BeanFactory interface not registered as resolvable type in a plain factory.
    // MessageSource registered (and found for autowiring) as a bean.
    // 注册自动装配的类
    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.
    beanFactory.addBeanPostProcessor(new ApplicationListenerDetector(this));
    // Detect a LoadTimeWeaver and prepare for weaving, if found.
    // 是否需要类加载期间织入  增加Aspectj的支持
    if (!IN_NATIVE_IMAGE && 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());
    }
}

这块代码比较长,但是逻辑比较简单,就直接贴代码了。

再对代码进行分析,主要经历以下几个阶段:

  1. addBeanPostProcessor 添加 BeanPostProcessor
  2. registerResolvableDependency 注册依赖关系
  3. registerSingleton 注册其他的单例 Bean

下面可以 Debug 看一下。


Debug

方法调用前:

网络异常,图片无法展示
|


registerResolvableDependency 执行之后

网络异常,图片无法展示
|

这里发现调用 registerResolvableDependency 执行结束之后,beanDefinitionNames 中并没有多添加相关对象。


查看源码发现其实是添加到了 resolvableDependencies 这个 Map 中了。

网络异常,图片无法展示
|
![]

回顾

在介绍 DefaultListableBeanFactory 时,说 BeanDefinition 是存储在 beanDefinitionMap 中的。 而这里的依赖关系是则是存储在 resolvableDependencies 中的。


postProcessBeanFactory

在执行 prepareBeanFactory 之后,当看到 postProcessBeanFactory(beanFactory); 方法的时候就很疑惑, 因为这个是需要子类实现的,只是作为一个模板方法,子类实现之后,可以在里面添加自己的逻辑。


总结


这篇文章相对比较简单,就是准备 BeanFactory 向其中添加系统的依赖以及 bean, 而 postProcessBeanFactory 则是一个模版方法用来供子类实现。

网络异常,图片无法展示
|


目录
相关文章
|
1月前
|
JavaScript Java 测试技术
基于springboot+vue.js+uniapp的公考学习平台附带文章源码部署视频讲解等
基于springboot+vue.js+uniapp的公考学习平台附带文章源码部署视频讲解等
34 5
|
1月前
|
Java 数据格式 微服务
2024最新首发,全网最全 Spring Boot 学习宝典(附思维导图)
📚 《滚雪球学Spring Boot》是由CSDN博主bug菌创作的全面Spring Boot教程。作者是全栈开发专家,在多个技术社区如CSDN、掘金、InfoQ、51CTO等担任博客专家,并拥有超过20万的全网粉丝。该教程分为入门篇和进阶篇,每篇包含详细的教学步骤,涵盖Spring Boot的基础和高级主题。
108 4
2024最新首发,全网最全 Spring Boot 学习宝典(附思维导图)
|
1月前
|
JavaScript Java 测试技术
基于SpringBoot+Vue+uniapp的在线学习过程管理系统的详细设计和实现(源码+lw+部署文档+讲解等)
基于SpringBoot+Vue+uniapp的在线学习过程管理系统的详细设计和实现(源码+lw+部署文档+讲解等)
基于SpringBoot+Vue+uniapp的在线学习过程管理系统的详细设计和实现(源码+lw+部署文档+讲解等)
|
22天前
|
Java Spring 容器
Spring Boot 启动源码解析结合Spring Bean生命周期分析
Spring Boot 启动源码解析结合Spring Bean生命周期分析
60 11
|
20天前
|
安全 Java 数据库
三更草堂 Spring Security学习总结(思路整理)
Spring Security学习总结(思路整理)
|
23天前
|
缓存 Java 程序员
spring IoC 源码
spring IoC 源码
38 3
|
1月前
|
JavaScript Java 测试技术
基于SpringBoot+Vue+uniapp的大学生国学自主学习平台的详细设计和实现(源码+lw+部署文档+讲解等)
基于SpringBoot+Vue+uniapp的大学生国学自主学习平台的详细设计和实现(源码+lw+部署文档+讲解等)
|
1月前
|
JavaScript Java 测试技术
基于SpringBoot+Vue+uniapp的诗词学习系统的详细设计和实现(源码+lw+部署文档+讲解等)
基于SpringBoot+Vue+uniapp的诗词学习系统的详细设计和实现(源码+lw+部署文档+讲解等)
|
1月前
|
JavaScript Java 测试技术
基于springboot+vue.js+uniapp的学生网课学习效果评价附带文章源码部署视频讲解等
基于springboot+vue.js+uniapp的学生网课学习效果评价附带文章源码部署视频讲解等
51 2
|
1月前
|
JavaScript Java 测试技术
基于springboot+vue.js+uniapp的语言课学习系统附带文章源码部署视频讲解等
基于springboot+vue.js+uniapp的语言课学习系统附带文章源码部署视频讲解等
27 3