Spring Framework 启动流程分析
Spring Framework 是一个功能强大且灵活的用于构建企业级 Java 应用程序的框架。理解 Spring Framework 的启动流程对于深入掌握其工作机制、调试应用程序以及进行高级定制非常重要。本文将详细介绍 Spring Framework 的启动流程,并结合关键源码类和方法进行说明。
应用程序的入口点
在 Spring Framework 中,应用程序的启动通常涉及创建和配置一个 ApplicationContext
。常见的方式包括使用 ClassPathXmlApplicationContext
、AnnotationConfigApplicationContext
或通过 ContextLoader
在 Web 应用中加载上下文。
以下是使用 AnnotationConfigApplicationContext
启动一个简单 Spring 应用的示例:
1 | public class MyApp { |
关键源码
AnnotationConfigApplicationContext
类该类是基于 Java 配置的
ApplicationContext
实现。它主要负责扫描和注册基于注解的配置类和组件。1
2
3public class AnnotationConfigApplicationContext extends GenericApplicationContext implements AnnotationConfigRegistry {
// 构造函数和方法
}
创建 ApplicationContext
实例
以 AnnotationConfigApplicationContext
为例,其构造函数会执行以下步骤:
1 | public AnnotationConfigApplicationContext(Class<?>... annotatedClasses) { |
关键步骤解析
注册配置类
register
方法将传入的配置类注册到上下文中。1
2
3
4
5
public void register(Class<?>... componentClasses) {
Assert.notEmpty(componentClasses, "At least one component class must be specified");
this.reader.loadBeanDefinitions(new AnnotatedBeanDefinitionReader(this).register(componentClasses).getRegistry());
}刷新上下文
refresh
方法是AbstractApplicationContext
中的重要方法,负责初始化上下文,包括加载 Bean 定义、初始化 BeanFactory、触发生命周期回调等。1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
public void refresh() throws BeansException, IllegalStateException {
synchronized (this.startupShutdownMonitor) {
// 准备此上下文进行刷新
prepareRefresh();
// 告诉子类刷新内部Bean工厂
ConfigurableListableBeanFactory beanFactory = obtainFreshBeanFactory();
// 准备Bean工厂以供此上下文使用
prepareBeanFactory(beanFactory);
try {
// 允许在上下文子类中对Bean工厂进行后处理
postProcessBeanFactory(beanFactory);
// 调用注册为上下文中的Bean的工厂处理器
invokeBeanFactoryPostProcessors(beanFactory);
// 注册拦截Bean创建的Bean处理器
registerBeanPostProcessors(beanFactory);
// 初始化此上下文的消息源
initMessageSource();
// 初始化此上下文的事件多播器
initApplicationEventMulticaster();
// 在特定的上下文子类中初始化其他特殊Bean
onRefresh();
// 检查监听器Bean并注册它们
registerListeners();
// 实例化所有剩余的(非延迟初始化)单例
finishBeanFactoryInitialization(beanFactory);
// 最后一步:发布相应的事件
finishRefresh();
} catch (BeansException ex) {
...
} finally {
// 重置Spring核心中的公共缓存,因为我们可能不再需要单例Bean的元数据了...
resetCommonCaches();
}
}
}
准备刷新上下文
prepareRefresh
方法执行一些准备工作,如设置启动标志、初始化 Environment
、PropertySources
等。
1 | protected void prepareRefresh() { |
获取和配置 BeanFactory
obtainFreshBeanFactory
方法负责创建或获取一个全新的 BeanFactory
实例,并加载 Bean 定义。
1 | protected ConfigurableListableBeanFactory obtainFreshBeanFactory() { |
refreshBeanFactory
方法在
GenericApplicationContext
中,该方法通常会创建一个DefaultListableBeanFactory
并加载 Bean 定义。1
2
3
4
5
6
7
8
9
10
11
12protected void refreshBeanFactory() throws BeansException, IllegalStateException {
if (this.beanFactory != null) {
destroyBeans();
closeBeanFactory();
}
DefaultListableBeanFactory beanFactory = new DefaultListableBeanFactory(getInternalParentBeanFactory());
beanFactory.setSerializationId(getId());
// 加载 Bean 定义
loadBeanDefinitions(beanFactory);
this.beanFactory = beanFactory;
}
准备 BeanFactory
prepareBeanFactory
方法对 BeanFactory
进行一些通用的设置,如设置类加载器,设置默认忽略依赖类型,注册早先的 BeanPostProcessors等。
1 | protected void prepareBeanFactory(ConfigurableListableBeanFactory beanFactory) { |
关键设置
- 类加载器:确保
BeanFactory
使用正确的类加载器。 - 忽略依赖接口:注册一些特殊接口,如
EnvironmentAware
、ApplicationContextAware
等,使BeanFactory
在自动装配时忽略这些接口。 - ApplicationListenerDetector:注册早期后处理器,用于将内部 bean 检测为 ApplicationListeners。
应用 BeanFactory 后处理器
invokeBeanFactoryPostProcessors
方法执行所有注册的 BeanFactoryPostProcessor
,如 PropertyPlaceholderConfigurer
、ConfigurationClassPostProcessor
等。
1 | void invokeBeanFactoryPostProcessors(ConfigurableListableBeanFactory beanFactory) { |
关键 Post-Processors
**
ConfigurationClassPostProcessor
**:解析@Configuration
类,处理注解如@Bean
、@ComponentScan
等,注册相应的 Bean 定义。1
2
3
4
5
6
public void postProcessBeanFactory(ConfigurableListableBeanFactory beanFactory) throws BeansException {
// 解析配置类
SourceClass sourceClass = new SourceClass(configurationClass);
// 处理 @Bean、@ComponentScan 等注解
}**
PropertySourcesPlaceholderConfigurer
**:解析@Value
注解中的占位符,并替换为实际的属性值。
注册 BeanPostProcessors
registerBeanPostProcessors
方法负责注册所有的 BeanPostProcessor
,如 AutowiredAnnotationBeanPostProcessor
、CommonAnnotationBeanPostProcessor
等。
1 | protected void registerBeanPostProcessors(ConfigurableListableBeanFactory beanFactory) { |
关键 BeanPostProcessors
- **
AutowiredAnnotationBeanPostProcessor
**:处理@Autowired
和@Value
注解,实现自动装配。 - **
CommonAnnotationBeanPostProcessor
**:处理 JSR-250 注解,如@PostConstruct
、@PreDestroy
等。 - **
RequiredAnnotationBeanPostProcessor
**:处理@Required
注解,确保依赖项被正确注入。
初始化 MessageSource
如果应用程序需要国际化支持,initializeMessageSource
方法会初始化 MessageSource
。
1 | protected void initializeMessageSource() { |
完成 BeanFactory 初始化
finishBeanFactoryInitialization
方法完成 BeanFactory 的初始化,包括实例化所有非懒加载的单例 Bean。
1 | protected void finishBeanFactoryInitialization(ConfigurableListableBeanFactory beanFactory) { |
预实例化单例 Bean
preInstantiateSingletons
方法遍历所有的 Bean 定义,并实例化非懒加载的单例 Bean。
1 | public void preInstantiateSingletons() throws BeansException { |
完成刷新上下文
finishRefresh
方法执行一些收尾工作,如发布 ContextRefreshedEvent
事件、启动生命周期 Bean(如 Lifecycle
接口实现的 Bean)等。
1 | protected void finishRefresh() { |
使用 ApplicationContext
一旦 ApplicationContext
完成初始化,应用程序就可以使用它来获取 Bean、发布事件等。
1 | MyBean myBean = context.getBean(MyBean.class); |
关闭上下文
在应用程序结束时,调用 close
方法关闭 ApplicationContext
,触发销毁钩子和 DisposableBean
接口的回调。
1 | context.close(); |
关键方法
1 | public void close() { |
总结
Spring Framework 的启动流程涉及多个关键步骤,每个步骤都通过多个类和方法协同工作,以确保应用程序的正确初始化和运行。以下是主要步骤和相关关键组件的总结:
- 创建 ApplicationContext:通过特定的
ApplicationContext
实现(如AnnotationConfigApplicationContext
)创建上下文实例。 - 注册配置类或 Bean 定义:使用注解或 XML 文件注册应用程序的 Bean 定义。
- 刷新上下文:
- 准备刷新:设置环境、初始化属性源等。
- 获取和配置 BeanFactory:创建
BeanFactory
实例,设置类加载器、忽略接口等。 - 应用 BeanFactoryPostProcessors:执行所有的
BeanFactoryPostProcessor
,如ConfigurationClassPostProcessor
。 - 注册 BeanPostProcessors:注册所有的
BeanPostProcessor
,如AutowiredAnnotationBeanPostProcessor
。 - 初始化 MessageSource:如果需要,初始化消息源用于国际化。
- 完成 BeanFactory 初始化:预实例化所有非懒加载的单例 Bean。
- 完成刷新:初始化生命周期管理器,发布
ContextRefreshedEvent
事件。
- 使用 ApplicationContext:获取和使用 Bean,发布事件等。
- 关闭上下文:在应用程序结束时,关闭上下文,触发销毁钩子和事件。
通过以上步骤,Spring Framework 能够高效地管理生命周期、依赖注入、Bean 的创建与销毁、事件发布等核心功能。理解这些流程和相关源码,对于深入掌握 Spring Framework 的工作机制、优化应用程序性能以及进行高级定制具有重要意义。