Spring的IoC容器初始化及Bean创建的关键步骤

        深入解析Spring源码涉及众多细节,这里我将按照一个简化流程,基于Spring的IoC容器初始化及Bean创建的关键步骤进行解析,主要关注ApplicationContext的初始化过程和Bean的实例化逻辑。


1. 应用上下文初始化 (ApplicationContext 初始化)
        入口点:当你创建一个ApplicationContext实例时(比如new ClassPathXmlApplicationContext("applicationContext.xml")或使用注解配置的AnnotationConfigApplicationContext(AppConfig.class)),初始化过程开始。
        refresh()方法:调用ApplicationContext的refresh()方法是启动流程的核心。这个方法内部执行了一系列初始化步骤,包括但不限于:
        准备环境:设置Environment,确定配置属性来源。
        载入Bean定义:根据配置(XML、注解、Java配置类)加载Bean定义到BeanDefinitionRegistry。
        后处理器注册:注册BeanFactoryPostProcessor和BeanPostProcessor,这些后处理器将在Bean定义解析和Bean实例化过程中起作用。
        Bean工厂初始化:初始化DefaultListableBeanFactory,这是Spring最核心的Bean工厂实现。
        预实例化单例Bean:根据配置,预先实例化所有单例Bean。


2. Bean定义的加载与注册
        BeanDefinitionReader:负责读取配置信息并转换成Spring内部的数据结构BeanDefinition,这是描述Bean如何被创建和配置的元数据。
        BeanDefinitionRegistry:注册BeanDefinition的地方,它维护了一个Bean定义的Map,键是Bean的名字,值是对应的BeanDefinition。


3. Bean的实例化与依赖注入
        DefaultListableBeanFactory:是Bean实例化的核心,它实现了BeanFactory接口。
        实例化Bean:通过getBean()方法触发Bean的实例化。首先,它会检查缓存(如上所述的三级缓存)中是否已经有该Bean的实例。
        依赖解析:在实例化过程中,如果发现Bean有依赖,会递归调用getBean()来获取依赖的Bean实例。
        后处理器应用:BeanPostProcessor在Bean实例化前后发挥作用,例如处理@Autowired注解的自动注入。
        初始化方法调用:如果Bean定义中有指定初始化方法,则在Bean实例化后调用。


4. 生命周期管理
        初始化与销毁:通过实现InitializingBean接口、使用@PostConstruct注解或在BeanDefinition中指定初始化方法和销毁方法,Spring管理Bean的生命周期。


示例代码解析
        考虑一个简单的Bean创建过程,以ApplicationContext的初始化和一个Bean的实例化为例,源码层面的逻辑涉及很多类和层次,但核心思想是通过反射、工厂模式和策略模式等设计模式,实现高度可配置和灵活的Bean管理机制。
        深入理解Spring源码需要查阅org.springframework.beans.factory.support.DefaultListableBeanFactory、org.springframework.context.support.AbstractApplicationContext、org.springframework.beans.factory.config.BeanDefinition等类的实现细节,以及观察这些类如何协同工作,完成复杂的依赖管理和生命周期管理任务。

        在Spring框架中,ApplicationContext的refresh()方法是启动和更新应用程序上下文的核心操作。它涉及到多个步骤来确保容器正确地加载和初始化Bean。以下是refresh()方法执行的主要步骤,这些步骤通常由AbstractApplicationContext类实现

1. prepareRefresh()
        初始化上下文刷新状态:将refreshing标志设为true,表明当前正在刷新上下文。
        记录启动时间:记录容器启动的时间戳,便于后续监控和日志记录。
        初始化环境信息:通过this.environment初始化ConfigurableEnvironment,它是Spring环境抽象的实现,负责管理属性源和解析属性值。
        继承父上下文环境:如果有父上下文,它的环境会被合并到当前上下文中。
        配置系统属性覆盖:注册SystemPropertiesOverrideConfigurer,允许系统属性覆盖其他配置源中的同名属性。
        初始化资源加载器:如果有必要,会初始化一个资源加载器,用于加载配置文件或类路径资源。


2. obtainFreshBeanFactory()
        获取或刷新Bean工厂:如果上下文已经有一个Bean工厂(BeanFactory),尝试刷新它;否则,新建一个DefaultListableBeanFactory。
        配置Bean工厂:设置Bean工厂的基本属性,如类加载器、属性编辑器等,为Bean的定义和实例化做准备。


3. prepareBeanFactory(beanFactory)
        配置Bean工厂以适应ApplicationContext:这是关键步骤,确保Bean工厂具有ApplicationContext所需的功能。
        注册特殊Bean后处理器:如ApplicationContextAwareProcessor,使Bean能够感知ApplicationContext。
        注册环境和属性编辑器感知处理器:如EnvironmentAwareProcessor、EmbeddedValueResolverAwareProcessor,使Bean能访问环境信息和解析属性表达式。
        禁用Bean工厂的内部Bean暴露:确保内部实现细节不被外部直接访问。
        设置默认的自动装配策略:如AUTOWIRE_NO,除非特别配置,否则不自动装配。
        注册其他必要的后处理器和服务:如LoadTimeWeaverAwareProcessor、ApplicationListenerDetector等。


4. postProcessBeanFactory(beanFactory)
        允许自定义Bean工厂后处理:调用所有注册的BeanFactoryPostProcessor,这些后处理器可以在Bean定义加载完成后对Bean定义进行修改,例如属性值的替换、Bean定义的添加或修改等。


5. invokeBeanFactoryPostProcessors(beanFactory)
        执行Bean工厂后处理器:分为两步,首先执行不需要依赖其他Bean定义的后处理器,如PropertySourcesPlaceholderConfigurer处理属性占位符,然后执行可能依赖于其他Bean定义的后处理器。


6. registerBeanPostProcessors(beanFactory)
        注册Bean后处理器:发现并注册所有BeanPostProcessor,这些处理器在Bean实例化前后执行,负责诸如依赖注入、AOP代理、初始化前后回调等功能。


7. initializeMessageSource()
        初始化消息源:创建并配置MessageSource,用于国际化和本地化消息的解析和检索。


8. initApplicationEventMulticaster()
        初始化事件广播器:创建并配置ApplicationEventMulticaster,用于发布和传播应用程序事件。


9. onRefresh()
        提供扩展点:这是一个空方法,留给子类重写,以插入自定义的刷新逻辑。


10. registerListeners()
        注册事件监听器:遍历所有已知的Bean,如果Bean实现了ApplicationListener接口,就将其注册到事件广播器中。


11. finishBeanFactoryInitialization(beanFactory)
        完成Bean工厂初始化
        预实例化单例Bean:按照依赖顺序,实例化所有非懒加载的单例Bean,处理循环依赖问题。
        执行Bean的初始化方法:对于每个Bean,如果配置了初始化方法,则在实例化之后调用。


12. finishRefresh()
        最终完成刷新
        清理刷新状态:将refreshing标志设回false。
        发布容器刷新完成事件:通过事件广播器发布ContextRefreshedEvent,通知所有监听器容器刷新已完成。
        注册关闭钩子:如果配置了关闭钩子,向JVM注册,确保当JVM关闭时,可以优雅地关闭ApplicationContext。


        以上步骤详细描述了Spring容器从初始化到完全准备就绪的整个过程,展示了其高度可配置性和灵活性。理解这些步骤对于深入掌握Spring框架的工作原理至关重要。

  • 17
    点赞
  • 12
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值