说说 Spring 启动过程?

Spring 框架的启动过程较为复杂,涉及容器初始化、Bean 加载与创建等多个关键环节,以下从 Spring 框架(以传统 Spring 应用,如基于 ClassPathXmlApplicationContext 为例)Spring Boot 应用 两个维度,详细拆解启动流程:


一、传统 Spring 应用(基于 XML 配置,如 ClassPathXmlApplicationContext

以手动创建 ClassPathXmlApplicationContext 加载 XML 配置为例,核心流程如下:

1. 初始化准备阶段
  • 入口触发:开发者通过 new ClassPathXmlApplicationContext("applicationContext.xml") 显式启动 Spring 容器。
  • 资源定位:根据传入的 XML 路径(如 applicationContext.xml),Spring 会扫描类路径,定位到配置文件资源。
2. 容器创建与准备
  • 创建 BeanFactory
    内部会初始化 DefaultListableBeanFactory(Spring 核心 Bean 工厂实现),作为后续管理 Bean 的基础容器,负责 Bean 的注册、解析和创建。
  • 加载配置元数据
    通过 XmlBeanDefinitionReader 解析 XML 配置文件,将 <bean> 标签、<context:component-scan> 等配置,转化为 BeanDefinition(Bean 的“定义元数据”,包含类名、作用域、依赖等信息),并注册到 BeanFactory 中。
3. Bean 工厂后置处理(BeanFactoryPostProcessor
  • 执行时机:在 Bean 实例化前,对 BeanFactory 中的 BeanDefinition 进行修改或增强。
  • 典型应用
    • PropertyPlaceholderConfigurer:替换 BeanDefinition 中的属性占位符(如 ${db.url}),加载外部配置(.properties 文件)。
    • ConfigurationClassPostProcessor(若使用 @Configuration 注解):解析 Java 配置类,补充 BeanDefinition
4. Bean 后置处理器注册(BeanPostProcessor
  • 作用:在 Bean 实例化、初始化前后插入自定义逻辑(如属性注入、AOP 代理)。
  • 注册方式:Spring 会扫描 BeanFactory 中已注册的 BeanPostProcessor 类型的 BeanDefinition,提前实例化这些处理器,供后续 Bean 生命周期使用。
5. Bean 实例化与依赖注入
  • 触发条件
    • 对于非懒加载(lazy-init="false")的单例 Bean,Spring 会在容器启动阶段主动实例化;
    • 懒加载 Bean 会延迟到第一次被使用时实例化。
  • 核心流程
    1. 实例化:通过反射创建 Bean 对象(调用构造器)。
    2. 属性注入(DI):根据 BeanDefinition 中的依赖信息(如 @Autowired<property>),从 BeanFactory 中查找依赖的 Bean 并注入。
    3. 初始化前(BeanPostProcessor.postProcessBeforeInitialization:执行自定义增强(如修改 Bean 属性)。
    4. 初始化(InitializingBean.afterPropertiesSet 或自定义 init-method:执行 Bean 初始化逻辑。
    5. 初始化后(BeanPostProcessor.postProcessAfterInitialization:典型应用是 AOP 代理(如 AnnotationAwareAspectJAutoProxyCreator 会在此阶段为 Bean 创建代理对象)。
6. 容器启动完成
  • 所有非懒加载单例 Bean 完成实例化、依赖注入和初始化后,ApplicationContext 进入“就绪”状态,可对外提供 Bean 的获取与使用。

二、Spring Boot 应用(自动装配简化流程)

Spring Boot 基于“约定优于配置”,通过自动装配大幅简化启动流程,核心流程如下:

1. 启动类触发(@SpringBootApplication
  • 入口SpringApplication.run(MyApplication.class, args),其中 @SpringBootApplication 是复合注解,包含:
    • @Configuration:标记类为配置类,参与 Bean 定义扫描。
    • @ComponentScan:扫描当前包及子包下的 @Component@Service 等组件。
    • @EnableAutoConfiguration:开启自动装配,触发 spring.factories 中配置的自动配置类。
2. 初始化 SpringApplication
  • 核心准备
    • 推断应用类型(Servlet/WebFlux/Reactive);
    • 加载 ApplicationContextInitializer(用于提前初始化容器);
    • 加载 ApplicationListener(监听启动事件,如 ApplicationStartingEvent)。
3. 环境准备(Environment
  • 作用:加载外部配置(如 application.yml、系统属性、环境变量等),并将配置整合到 Environment 中,供后续流程使用。
  • 扩展点EnvironmentPostProcessor 可自定义环境配置(如加载额外配置文件)。
4. 创建 ApplicationContext
  • 类型选择:根据应用类型(Servlet 环境默认创建 AnnotationConfigServletWebServerApplicationContext)创建对应的 ApplicationContext
  • 与传统 Spring 衔接:内部依然依赖 DefaultListableBeanFactory 管理 Bean,但通过注解驱动替代 XML 解析。
5. 自动装配(@EnableAutoConfiguration
  • 核心逻辑
    Spring Boot 会读取 META-INF/spring.factoriesEnableAutoConfiguration 对应的配置类(如 DataSourceAutoConfigurationWebMvcAutoConfiguration 等),将这些配置类的 BeanDefinition 注册到容器。
  • 条件装配:通过 @Conditional 系列注解(如 @ConditionalOnClass@ConditionalOnBean),判断是否满足装配条件,避免无效 Bean 加载。
6. Bean 加载与初始化(同传统 Spring 核心流程)
  • 扫描 @ComponentScan 路径下的组件(@Service@Controller 等),结合自动装配的 BeanDefinition,执行 Bean 实例化、依赖注入、初始化 流程,最终完成容器启动。
7. Web 服务器启动(Servlet 环境)
  • 若为 Web 应用,ServletWebServerApplicationContext 会触发 TomcatWebServer(或其他嵌入式服务器)的启动,绑定端口并初始化 Servlet 容器,使应用具备 HTTP 服务能力。
8. 发布启动事件
  • 容器启动完成后,发布 ApplicationReadyEvent,通知监听者(如自定义 ApplicationListener)应用已就绪,可处理外部请求。

三、核心区别与总结

对比维度传统 Spring 应用Spring Boot 应用
配置方式依赖 XML 或手动 Java 配置注解驱动 + 自动装配,简化配置
启动入口手动创建 ApplicationContextSpringApplication.run() 统一入口
核心流程显式解析配置 → Bean 工厂初始化 → Bean 实例化自动装配 + 条件化配置,弱化 XML 依赖
Web 支持需手动集成 Servlet 容器(如 Tomcat)自动嵌入 Web 服务器(Tomcat/Undertow 等)

本质共性:无论传统 Spring 还是 Spring Boot,核心都是围绕 BeanFactory 管理 Bean 生命周期,通过 AOP 实现事务、代理,通过 DI 完成依赖注入。Spring Boot 本质是“更智能的 Spring 封装”,通过自动装配和约定简化了配置与启动流程,但底层逻辑与传统 Spring 一脉相承。

理解启动流程后,可更清晰排查问题(如 Bean 未加载、自动装配失效),也能合理扩展(如自定义 BeanFactoryPostProcessorApplicationContextInitializer 干预启动过程)。

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值