分析spring容器的启动
Spring 容器的启动过程涉及多个核心组件,我们可以结合源码进行深入分析。以下是各个关键步骤的详细解析:
1. 创建 ApplicationContext
Spring 允许多种 ApplicationContext
实现,如 AnnotationConfigApplicationContext
或 ClassPathXmlApplicationContext
。以 AnnotationConfigApplicationContext
为例:
AnnotationConfigApplicationContext context = new AnnotationConfigApplicationContext(AppConfig.class);
public AnnotationConfigApplicationContext(Class<?>... annotatedClasses) {
this();
register(annotatedClasses);
refresh(); // 核心方法
}
在 AnnotationConfigApplicationContext
的构造方法中,会调用refresh()
,该方法是是 Spring 容器启动的核心方法,它初始化 BeanFactory
并完成容器的加载。
2. 创建 BeanFactory
DefaultListableBeanFactory
是 Spring 默认的 BeanFactory
,它负责存储和管理所有的 BeanDefinition
。
protected void refreshBeanFactory() throws BeansException {
this.beanFactory = new DefaultListableBeanFactory();
}
AbstractApplicationContext
中的 refresh()
方法会创建 BeanFactory
,DefaultListableBeanFactory
主要作用是注册 bean 定义,但此时 bean 还未实例化。
3. 解析 BeanDefinition
Spring 解析 @ComponentScan
、@Bean
或 XML 配置,将其转换为 BeanDefinition
。
@Override
public void postProcessBeanDefinitionRegistry(BeanDefinitionRegistry registry) {
processConfigurationClasses(registry);
}
ConfigurationClassPostProcessor
解析 @Configuration
类,processConfigurationClasses(registry)
负责解析配置类,并将 bean 注册到 BeanFactory
中。
4. BeanFactory
初始化
Spring 允许 BeanFactory
进行自定义扩展,比如增加 BeanPostProcessor
。
invokeBeanFactoryPostProcessors(beanFactory);
refresh()
方法中会调用 invokeBeanFactoryPostProcessors(beanFactory),这一步会执行 BeanFactoryPostProcessor
,允许修改 BeanDefinition
。
5. ApplicationContextAware
处理
如果一个 bean 实现了 ApplicationContextAware
,Spring 会自动为其注入 ApplicationContext
。
public Object postProcessBeforeInitialization(Object bean, String beanName) throws BeansException {
if (bean instanceof ApplicationContextAware) {
((ApplicationContextAware) bean).setApplicationContext(applicationContext);
}
return bean;
}
在 ApplicationContextAwareProcessor
中,bean 已经可以访问 ApplicationContext
。
6. 加载 BeanPostProcessor
Spring 会寻找 BeanPostProcessor
,用于在 bean 实例化前后执行额外逻辑,比如 AOP 代理。
protected void registerBeanPostProcessors(ConfigurableListableBeanFactory beanFactory) {
for (BeanPostProcessor processor : beanFactory.getBeanPostProcessors()) {
beanFactory.addBeanPostProcessor(processor);
}
}
在 AbstractApplicationContext
的 registerBeanPostProcessors()
方法中,这些 BeanPostProcessor
可能会影响 bean 的生命周期,比如代理生成。
7. 触发 ApplicationEvent
Spring 会发送 ContextRefreshedEvent
事件,通知所有 ApplicationListener
容器已经启动。
publishEvent(new ContextRefreshedEvent(this));
在 AbstractApplicationContext
的 finishRefresh()
方法中,这一步会触发所有监听器,执行 onApplicationEvent(ContextRefreshedEvent event) 方法。
8. 准备创建 Bean
Spring 开始实例化所有 非懒加载 的单例 bean。
public void preInstantiateSingletons() throws BeansException {
for (String beanName : this.beanDefinitionNames) {
getBean(beanName);
}
}
在 DefaultListableBeanFactory
的 preInstantiateSingletons()
方法中,Spring 完成 bean 的实例化,准备对外提供服务。
通过源码分析可以看到,Spring 的启动过程遵循 配置解析 → BeanFactory 初始化 → Bean 解析 → 生命周期管理 的逻辑。
- 点赞
- 收藏
- 关注作者
评论(0)