📚 前言
Spring框架作为Java生态中最流行的框架之一,其启动流程一直是Java开发者需要深入理解的重要知识点。本文将从源码角度深入分析Spring的完整启动流程,帮助你理解Spring容器是如何初始化并管理Bean的。通过本文,你将了解Spring启动过程中的每一个关键步骤,掌握Spring容器的核心工作原理。
🔍 Spring启动流程概述
Spring的启动流程主要分为两个阶段:容器初始化和容器刷新。在这两个阶段中,Spring完成了从配置解析到Bean实例化、初始化的全过程。
🏗️ 一、容器初始化阶段
容器初始化阶段主要完成以下工作:
1.创建Spring容器(ApplicationContext)
2.准备必要的工具类和组件
3.加载和解析配置
1.1 创建ApplicationContext
以AnnotationConfigApplicationContext为例(基于Java配置类的方式),其构造过程如下:
java
// 创建AnnotationConfigApplicationContext对象
AnnotationConfigApplicationContext context = new AnnotationConfigApplicationContext(AppConfig.class);
这行代码背后发生了什么?让我们看看源码:
java
public AnnotationConfigApplicationContext(Class<?>... componentClasses) {
// 调用无参构造函数
this();
// 注册配置类
register(componentClasses);
// 刷新容器
refresh();
}
public AnnotationConfigApplicationContext() {
// 创建一个读取注解的Bean定义读取器
this.reader = new AnnotatedBeanDefinitionReader(this);
// 创建一个扫描器,用于扫描包或类,转换为BeanDefinition
this.scanner = new ClassPathBeanDefinitionScanner(this);
}
💡 关键点:在创建AnnotationConfigApplicationContext时,Spring首先会创建一个Bean工厂(DefaultListableBeanFactory),然后创建注解Bean定义读取器和类路径扫描器,为后续的Bean扫描和注册做准备。
1.2 创建AnnotatedBeanDefinitionReader
AnnotatedBeanDefinitionReader用于读取注解配置,并将其转换为BeanDefinition。在创建过程中,会注册一些基础的后置处理器:
java
public AnnotatedBeanDefinitionReader(BeanDefinitionRegistry registry, Environment environment) {
Assert.notNull(registry, "BeanDefinitionRegistry must not be null");
Assert.notNull(environment, "Environment must not be null");
this.registry = registry;
this.conditionEvaluator = new ConditionEvaluator(registry, environment, null);
// 注册注解配置处理器
AnnotationConfigUtils.registerAnnotationConfigProcessors(this.registry);
}
在registerAnnotationConfigProcessors方法中,会注册以下关键组件:
java
public static Set<BeanDefinitionHolder> registerAnnotationConfigProcessors(
BeanDefinitionRegistry registry, @Nullable Object source) {
// 注册ConfigurationClassPostProcessor,用于处理@Configuration、@Import等注解
if (!registry.containsBeanDefinition(CONFIGURATION_ANNOTATION_PROCESSOR_BEAN_NAME)) {
RootBeanDefinition def = new RootBeanDefinition(ConfigurationClassPostProcessor.class);
def.setSource(source);
beanDefs.add(registerPostProcessor(registry, def, CONFIGURATION_ANNOTATION_PROCESSOR_BEAN_NAME));
}
// 注册AutowiredAnnotationBeanPostProcessor,用于处理@Autowired注解
if (!registry.containsBeanDefinition(AUTOWIRED_ANNOTATION_PROCESSOR_BEAN_NAME)) {
RootBeanDefinition def = new RootBeanDefinition(AutowiredAnnotationBeanPostProcessor.class);
def.setSource(source);
beanDefs.add(registerPostProcessor(registry, def, AUTOWIRED_ANNOTATION_PROCESSOR_BEAN_NAME));
}
// 注册CommonAnnotationBeanPostProcessor,用于处理@Resource等注解
if (!registry.containsBeanDefinition(COMMON_ANNOTATION_PROCESSOR_BEAN_NAME)) {
RootBeanDefinition def = new RootBeanDefinition(CommonAnnotationBeanPostProcessor.class);
def.setSource(source);
beanDefs.add(registerPostProcessor(registry, def, COMMON_ANNOTATION_PROCESSOR_BEAN_NAME));
}
// 其他处理器注册...
return beanDefs;
}
🔍 注意:这些后置处理器是Spring框架的核心组件,它们负责处理各种注解,实现依赖注入、AOP等功能。
1.3 创建ClassPathBeanDefinitionScanner
ClassPathBeanDefinitionScanner用于扫描指定包路径下的类,并将符合条件的类转换为BeanDefinition:
java
public ClassPathBeanDefinitionScanner(BeanDefinitionRegistry registry) {
this(registry, true);
}
public ClassPathBeanDefinitionScanner(BeanDefinitionRegistry registry, boolean useDefaultFilters) {
this(registry, useDefaultFilters, getOrCreateEnvironment(registry));
}
public ClassPathBeanDefinitionScanner(BeanDefinitionRegistry registry, boolean useDefaultFilters,
Environment environment) {
this(registry, useDefaultFilters, environment,
(registry instanceof ResourceLoader ? (ResourceLoader) registry : null));
}
在构造过程中,会设置默认的过滤器,用于筛选带有@Component、@Repository、@Service和@Controller注解的类。
1.4 注册配置类
在创建完AnnotationConfigApplicationContext后,会调用register方法注册配置类:
java
public void register(Class<?>... componentClasses) {
for (Class<?> componentClass : componentClasses) {
registerBean(componentClass);
}
}
public void registerBean(Class<?> beanClass) {
doRegisterBean(beanClass, null, null, null);
}
<T> void doRegisterBean(Class<T> beanClass, @Nullable String name,
@Nullable Class<? extends Annotation>[] qualifiers, @Nullable Supplier<T> supplier,
@Nullable BeanDefinitionCustomizer... customizers) {
// 创建AnnotatedGenericBeanDefinition,包含了类的各种元信息
AnnotatedGenericBeanDefinition abd = new AnnotatedGenericBeanDefinition(beanClass);
// 判断是否需要跳过注册
if (this.conditionEvaluator.shouldSkip(abd.getMetadata())) {
return;
}
// 设置Bean的作用域等信息
ScopeMetadata scopeMetadata = this.scopeMetadataResolver.resolveScopeMetadata(abd);
abd.setScope(scopeMetadata.getScopeName());
String beanName = (name != null ? name : this.beanNameGenerator.generateBeanName(abd, this.registry));
// 处理通用注解
AnnotationConfigUtils.processCommonDefinitionAnnotations(abd);
// 处理限定符注解
if (qualifiers != null) {
for (Class<? extends Annotation> qualifier : qualifiers) {
if (Primary.class == qualifier) {
abd.setPrimary(true);
}
else if (Lazy.class == qualifier) {
abd.setLazyInit(true);
}
else {
abd.addQualifier(new AutowireCandidateQualifier(qualifier));
}
}
}
// 应用自定义设置
if (customizers != null) {
for (BeanDefinitionCustomizer customizer : customizers) {
customizer.customize(abd);
}
}
// 创建BeanDefinitionHolder并注册
BeanDefinitionHolder definitionHolder = new BeanDefinitionHolder(abd, beanName);
definitionHolder = AnnotationConfigUtils.applyScopedProxyMode(scopeMetadata, definitionHolder, this.registry);
BeanDefinitionReaderUtils.registerBeanDefinition(definitionHolder, this.registry);
}
🌟 重要:这一步将配置类本身注册为一个Bean,这样Spring才能对其进行处理,解析其中的配置信息。
🔄 二、容器刷新阶段
容器刷新是Spring启动过程中最核心的部分,通过调用refresh()方法完成。这个方法定义在AbstractApplicationContext类中,包含了12个关键步骤:
java
@Override
public void refresh() throws BeansException, IllegalStateException {
synchronized (this.startupShutdownMonitor) {
// 1. 准备刷新上下文环境
prepareRefresh();
// 2. 获取BeanFactory,对于AnnotationConfigApplicationContext,直接返回已创建的BeanFactory
ConfigurableListableBeanFactory beanFactory = obtainFreshBeanFactory();
// 3. 准备BeanFactory,设置类加载器、后置处理器等
prepareBeanFactory(beanFactory);
try {
// 4. 允许子类在标准初始化后修改BeanFactory
postProcessBeanFactory(beanFactory);
// 5. 执行BeanFactoryPostProcessor
invokeBeanFactoryPostProcessors(beanFactory);
// 6. 注册BeanPostProcessor
registerBeanPostProcessors(beanFactory);
// 7. 初始化消息源
initMessageSource();
// 8. 初始化事件广播器
initApplicationEventMulticaster();
// 9. 初始化特定上下文子类中的其他特殊Bean
onRefresh();
// 10. 注册监听器
registerListeners();
// 11. 初始化所有非懒加载的单例Bean
finishBeanFactoryInitialization(beanFactory);
// 12. 完成刷新,发布相应的事件
finishRefresh();
}
catch (BeansException ex) {
// 销毁已创建的Bean
destroyBeans();
// 取消刷新
cancelRefresh(ex);
throw ex;
}
finally {
// 重置通用缓存
resetCommonCaches();
}
}
}
下面我们详细分析这12个步骤:
2.1 prepareRefresh - 准备刷新
java
protected void prepareRefresh() {
// 记录启动时间
this.startupDate = System.currentTimeMillis();
this.closed.set(false);
this.active.set(true);
// 初始化属性源
initPropertySources();
// 验证必要的属性
getEnvironment().validateRequiredProperties();
// 存储早期的应用事件
if (this.earlyApplicationEvents == null) {
this.earlyApplicationEvents = new LinkedHashSet<>();
}
}
这一步主要是做一些准备工作,包括记录启动时间、初始化属性源、验证必要的属性等。
2.2 obtainFreshBeanFactory - 获取BeanFactory
java
protected ConfigurableListableBeanFactory obtainFreshBeanFactory() {
refreshBeanFactory();
return getBeanFactory();
}
对于AnnotationConfigApplicationContext,这一步直接返回已创建的DefaultListableBeanFactory。
2.3 prepareBeanFactory - 准备BeanFactory
java
protected void prepareBeanFactory(ConfigurableListableBeanFactory beanFactory) {
// 设置类加载器
beanFactory.setBeanClassLoader(getClassLoader());
// 设置表达式解析器
beanFactory.setBeanExpressionResolver(new StandardBeanExpressionResolver(beanFactory.getBeanClassLoader()));
// 添加属性编辑器注册器
beanFactory.addPropertyEditorRegistrar(new ResourceEditorRegistrar(this, getEnvironment()));
// 添加ApplicationContextAwareProcessor,处理各种Aware接口
beanFactory.addBeanPostProcessor(new ApplicationContextAwareProcessor(this));
// 设置忽略的依赖接口
beanFactory.ignoreDependencyInterface(EnvironmentAware.class);
beanFactory.ignoreDependencyInterface(EmbeddedValueResolverAware.class);
beanFactory.ignoreDependencyInterface(ResourceLoaderAware.class);
beanFactory.ignoreDependencyInterface(ApplicationEventPublisherAware.class);
beanFactory.ignoreDependencyInterface(MessageSourceAware.class);
beanFactory.ignoreDependencyInterface(ApplicationContextAware.class);
// 注册可解析的依赖
beanFactory.registerResolvableDependency(BeanFactory.class, beanFactory);
beanFactory.registerResolvableDependency(ResourceLoader.class, this);
beanFactory.registerResolvableDependency(ApplicationEventPublisher.class, this);
beanFactory.registerResolvableDependency(ApplicationContext.class, this);
// 添加ApplicationListenerDetector
beanFactory.addBeanPostProcessor(new ApplicationListenerDetector(this));
// 添加LoadTimeWeaverAwareProcessor
if (beanFactory.containsBean(LOAD_TIME_WEAVER_BEAN_NAME)) {
beanFactory.addBeanPostProcessor(new LoadTimeWeaverAwareProcessor(beanFactory));
// Set a temporary ClassLoader for type matching.
beanFactory.setTempClassLoader(new ContextTypeMatchClassLoader(beanFactory.getBeanClassLoader()));
}
// 注册默认环境Bean
if (!beanFactory.containsLocalBean(ENVIRONMENT_BEAN_NAME)) {
beanFactory.registerSingleton(ENVIRONMENT_BEAN_NAME, getEnvironment());
}
if (!beanFactory.containsLocalBean(SYSTEM_PROPERTIES_BEAN_NAME)) {
beanFactory.registerSingleton(SYSTEM_PROPERTIES_BEAN_NAME, getEnvironment().getSystemProperties());
}
if (!beanFactory.containsLocalBean(SYSTEM_ENVIRONMENT_BEAN_NAME)) {
beanFactory.registerSingleton(SYSTEM_ENVIRONMENT_BEAN_NAME, getEnvironment().getSystemEnvironment());
}
}
这一步为BeanFactory设置了各种属性和组件,包括类加载器、表达式解析器、属性编辑器、后置处理器等,还注册了一些默认的单例Bean。
2.4 postProcessBeanFactory - 允许子类修改BeanFactory
java
protected void postProcessBeanFactory(ConfigurableListableBeanFactory beanFactory) {
// 空实现,留给子类扩展
}
这是一个模板方法,允许子类在标准初始化后修改BeanFactory。
2.5 invokeBeanFactoryPostProcessors - 执行BeanFactoryPostProcessor
java
protected void invokeBeanFactoryPostProcessors(ConfigurableListableBeanFactory beanFactory) {
PostProcessorRegistrationDelegate.invokeBeanFactoryPostProcessors(beanFactory, getBeanFactoryPostProcessors());
// 如果LoadTimeWeaver可用,则添加LoadTimeWeaverAwareProcessor
if (beanFactory.getTempClassLoader() == null && beanFactory.containsBean(LOAD_TIME_WEAVER_BEAN_NAME)) {
beanFactory.addBeanPostProcessor(new LoadTimeWeaverAwareProcessor(beanFactory));
beanFactory.setTempClassLoader(new ContextTypeMatchClassLoader(beanFactory.getBeanClassLoader()));
}
}
这一步执行所有的BeanFactoryPostProcessor
,包括我们在1.2节中注册的ConfigurationClassPostProcessor
。ConfigurationClassPostProcessor
会处理@Configuration
、@ComponentScan
、@Import
等注解,完成Bean的扫描和注册。
🔥 核心步骤:这是Spring启动过程中最核心的步骤之一,完成了Bean的扫描和注册。
2.6 registerBeanPostProcessors - 注册BeanPostProcessor
java
protected void registerBeanPostProcessors(ConfigurableListableBeanFactory beanFactory) {
PostProcessorRegistrationDelegate.registerBeanPostProcessors(beanFactory, this);
}
这一步注册所有的BeanPostProcessor
,包括我们在1.2节中注册的AutowiredAnnotationBeanPostProcessor
和CommonAnnotationBeanPostProcessor
。这些后置处理器会在Bean的初始化前后执行,实现依赖注入等功能。
2.7 initMessageSource - 初始化消息源
java
protected void initMessageSource() {
ConfigurableListableBeanFactory beanFactory = getBeanFactory();
if (beanFactory.containsLocalBean(MESSAGE_SOURCE_BEAN_NAME)) {
this.messageSource = beanFactory.getBean(MESSAGE_SOURCE_BEAN_NAME, MessageSource.class);
// 设置父消息源
if (this.parent != null && this.messageSource instanceof HierarchicalMessageSource) {
HierarchicalMessageSource hms = (HierarchicalMessageSource) this.messageSource;
if (hms.getParentMessageSource() == null) {
hms.setParentMessageSource(getInternalParentMessageSource());
}
}
}
else {
// 创建默认的消息源
DelegatingMessageSource dms = new DelegatingMessageSource();
dms.setParentMessageSource(getInternalParentMessageSource());
this.messageSource = dms;
beanFactory.registerSingleton(MESSAGE_SOURCE_BEAN_NAME, this.messageSource);
}
}
这一步初始化消息源,用于国际化。
2.8 initApplicationEventMulticaster - 初始化事件广播器
java
protected void initApplicationEventMulticaster() {
ConfigurableListableBeanFactory beanFactory = getBeanFactory();
if (beanFactory.containsLocalBean(APPLICATION_EVENT_MULTICASTER_BEAN_NAME)) {
this.applicationEventMulticaster =
beanFactory.getBean(APPLICATION_EVENT_MULTICASTER_BEAN_NAME, ApplicationEventMulticaster.class);
}
else {
// 创建默认的事件广播器
this.applicationEventMulticaster = new SimpleApplicationEventMulticaster(beanFactory);
beanFactory.registerSingleton(APPLICATION_EVENT_MULTICASTER_BEAN_NAME, this.applicationEventMulticaster);
}
}
这一步初始化事件广播器,用于发布应用事件。
2.9 onRefresh - 初始化特定上下文子类中的其他特殊Bean
java
protected void onRefresh() {
// 空实现,留给子类扩展
}
这是一个模板方法,允许子类在容器刷新时初始化其他特殊Bean。
2.10 registerListeners - 注册监听器
java
protected void registerListeners() {
// 注册静态指定的监听器
for (ApplicationListener<?> listener : getApplicationListeners()) {
getApplicationEventMulticaster().addApplicationListener(listener);
}
// 注册监听器Bean
String[] listenerBeanNames = getBeanNamesForType(ApplicationListener.class, true, false);
for (String listenerBeanName : listenerBeanNames) {
getApplicationEventMulticaster().addApplicationListenerBean(listenerBeanName);
}
// 发布早期的应用事件
Set<ApplicationEvent> earlyEventsToProcess = this.earlyApplicationEvents;
this.earlyApplicationEvents = null;
if (earlyEventsToProcess != null) {
for (ApplicationEvent earlyEvent : earlyEventsToProcess) {
getApplicationEventMulticaster().multicastEvent(earlyEvent);
}
}
}
这一步注册所有的事件监听器,并发布早期的应用事件。
2.11 finishBeanFactoryInitialization - 初始化所有非懒加载的单例Bean
java
protected void finishBeanFactoryInitialization(ConfigurableListableBeanFactory beanFactory) {
// 初始化转换服务
if (beanFactory.containsBean(CONVERSION_SERVICE_BEAN_NAME) &&
beanFactory.isTypeMatch(CONVERSION_SERVICE_BEAN_NAME, ConversionService.class)) {
beanFactory.setConversionService(
beanFactory.getBean(CONVERSION_SERVICE_BEAN_NAME, ConversionService.class));
}
// 注册默认的嵌入值解析器
if (!beanFactory.hasEmbeddedValueResolver()) {
beanFactory.addEmbeddedValueResolver(strVal -> getEnvironment().resolvePlaceholders(strVal));
}
// 初始化LoadTimeWeaverAware Bean
String[] weaverAwareNames = beanFactory.getBeanNamesForType(LoadTimeWeaverAware.class, false, false);
for (String weaverAwareName : weaverAwareNames) {
getBean(weaverAwareName);
}
// 停止使用临时类加载器
beanFactory.setTempClassLoader(null);
// 冻结配置
beanFactory.freezeConfiguration();
// 初始化所有非懒加载的单例Bean
beanFactory.preInstantiateSingletons();
}
这一步初始化所有非懒加载的单例Bean,是Spring启动过程中最核心的步骤之一。
💡 关键点:preInstantiateSingletons
方法会遍历所有的Bean定义,创建所有非懒加载的单例Bean。
2.12 finishRefresh - 完成刷新
java
protected void finishRefresh() {
// 清除资源缓存
clearResourceCaches();
// 初始化生命周期处理器
initLifecycleProcessor();
// 调用生命周期处理器的onRefresh方法
getLifecycleProcessor().onRefresh();
// 发布ContextRefreshedEvent事件
publishEvent(new ContextRefreshedEvent(this));
// 注册MBean
LiveBeansView.registerApplicationContext(this);
}
这一步完成容器的刷新,发布ContextRefreshedEvent事件,表示容器已经刷新完成。
🌱 三、Bean的生命周期
在Spring容器启动过程中,Bean的生命周期是一个重要的概念。下面是Bean的完整生命周期流程图:

Bean的生命周期主要包括以下步骤:
1.实例化Bean (Instantiate)
2.设置属性 (Populate Properties)
3.如果实现了BeanNameAware接口,调用setBeanName()
4.如果实现了BeanFactoryAware接口,调用setBeanFactory()
5.如果实现了ApplicationContextAware接口,调用setApplicationContext()
6.调用BeanPostProcessor的前置处理方法postProcessBeforeInitialization()
7.如果实现了InitializingBean接口,调用afterPropertiesSet()
8.调用自定义的init-method方法
9.调用BeanPostProcessor的后置处理方法postProcessAfterInitialization()
10.Bean可以使用了 (Bean Ready to Use)
11.如果实现了DisposableBean接口,调用destroy()
12.调用自定义的destroy-method方法
这些步骤在Spring容器的finishBeanFactoryInitialization方法中完成,具体实现在DefaultListableBeanFactory的preInstantiateSingletons方法和AbstractAutowireCapableBeanFactory的createBean方法中。
📝 总结
通过本文,我们深入分析了Spring的完整启动流程,包括容器初始化和容器刷新两个阶段。在这个过程中,Spring完成了从配置解析到Bean实例化、初始化的全过程。理解这个过程对于深入使用Spring框架、解决Spring相关问题非常有帮助。
Spring的启动流程虽然复杂,但是设计得非常优雅,通过各种设计模式(如模板方法、观察者、工厂等)实现了高度的可扩展性和灵活性。希望本文能帮助你更好地理解Spring的工作原理,在实际开发中更加得心应手。