深入解析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框架的工作原理至关重要。