面试题:说说 Spring 启动过程?

Spring 的启动过程是一个复杂的过程,涉及多个步骤和组件的协作。以下是 Spring 启动过程的主要阶段和关键步骤的详细说明:


1. 加载配置文件

Spring 启动的第一步是加载配置文件(如 applicationContext.xml 或 Java 配置类)。这些配置文件定义了 Bean 的定义、依赖关系、AOP 配置等。

  • XML 配置:通过 ClassPathXmlApplicationContext 或 FileSystemXmlApplicationContext 加载 XML 配置文件。
  • Java 配置:通过 AnnotationConfigApplicationContext 加载基于注解的配置类。
// XML 配置
ApplicationContext context = new ClassPathXmlApplicationContext("applicationContext.xml");

// Java 配置
ApplicationContext context = new AnnotationConfigApplicationContext(AppConfig.class);

2. 实例化 BeanFactory

Spring 的核心是 BeanFactory,它是 Spring IoC 容器的基础。在启动过程中,Spring 会创建一个 BeanFactory 实例,用于管理 Bean 的生命周期。

  • DefaultListableBeanFactory:Spring 默认使用的 BeanFactory 实现类。
  • BeanDefinition:Spring 会将配置文件中的 Bean 定义解析为 BeanDefinition 对象,并注册到 BeanFactory 中。

3. 解析 Bean 定义

Spring 会解析配置文件或注解中的 Bean 定义,并将其转换为 BeanDefinition 对象。BeanDefinition 包含了 Bean 的类名、作用域、依赖关系等信息。

  • XML 配置:通过 BeanDefinitionReader 解析 XML 文件。
  • 注解配置:通过 ClassPathBeanDefinitionScanner 扫描带有 @Component@Service 等注解的类。

4. 注册 Bean 定义

解析完 Bean 定义后,Spring 会将 BeanDefinition 注册到 BeanFactory 中。此时,Bean 还没有被实例化,只是定义了 Bean 的元数据。


5. 调用 BeanFactoryPostProcessor

BeanFactoryPostProcessor 是 Spring 提供的一个扩展点,允许在 Bean 实例化之前对 BeanDefinition 进行修改或增强。

  • 常见实现
    • PropertySourcesPlaceholderConfigurer:用于解析 ${} 占位符。
    • ConfigurationClassPostProcessor:用于处理 @Configuration 类。

6. 实例化 Bean

在 Bean 定义注册完成后,Spring 会根据 BeanDefinition 实例化 Bean。实例化的过程包括:

  • 依赖查找:根据 Bean 的依赖关系,查找并注入依赖的 Bean。
  • 构造函数或工厂方法:通过构造函数或工厂方法创建 Bean 实例。

7. 填充 Bean 属性

在 Bean 实例化后,Spring 会通过反射或 setter 方法将依赖的 Bean 注入到目标 Bean 中。这一步称为 依赖注入(DI)

  • @Autowired:自动注入依赖。
  • @Value:注入配置值。

8. 调用 BeanPostProcessor

BeanPostProcessor 是 Spring 提供的另一个扩展点,允许在 Bean 初始化前后执行自定义逻辑。

  • 常见实现
    • AutowiredAnnotationBeanPostProcessor:处理 @Autowired 和 @Value 注解。
    • CommonAnnotationBeanPostProcessor:处理 @PostConstruct 和 @PreDestroy 注解。

9. 初始化 Bean

在 Bean 的属性填充完成后,Spring 会调用 Bean 的初始化方法。初始化的方式包括:

  • 实现 InitializingBean 接口:调用 afterPropertiesSet() 方法。
  • 使用 @PostConstruct 注解:标记初始化方法。
  • 自定义初始化方法:在 XML 配置中指定 init-method

10. 完成启动

当所有 Bean 都实例化、依赖注入和初始化完成后,Spring 容器启动完成,应用程序可以正常使用这些 Bean。


11. 销毁 Bean

当 Spring 容器关闭时,会调用 Bean 的销毁方法。销毁的方式包括:

  • 实现 DisposableBean 接口:调用 destroy() 方法。
  • 使用 @PreDestroy 注解:标记销毁方法。
  • 自定义销毁方法:在 XML 配置中指定 destroy-method

12. 总结

Spring 的启动过程可以概括为以下几个关键步骤:

  1. 加载配置文件:读取 XML 或注解配置。
  2. 实例化 BeanFactory:创建 IoC 容器。
  3. 解析和注册 Bean 定义:将 Bean 定义转换为 BeanDefinition 并注册到容器中。
  4. 调用 BeanFactoryPostProcessor:修改或增强 Bean 定义。
  5. 实例化 Bean:创建 Bean 实例。
  6. 填充 Bean 属性:依赖注入。
  7. 调用 BeanPostProcessor:在 Bean 初始化前后执行自定义逻辑。
  8. 初始化 Bean:调用初始化方法。
  9. 完成启动:容器启动完成,Bean 可用。
  10. 销毁 Bean:容器关闭时调用销毁方法。

通过以上步骤,Spring 完成了容器的启动和 Bean 的生命周期管理。理解这些步骤有助于更好地掌握 Spring 的工作原理和解决实际问题。

THE END
点赞14 分享
评论 抢沙发
头像
欢迎您留下宝贵的见解!
提交
头像

昵称

取消
昵称表情代码图片

    暂无评论内容