Spring IOC 容器 refresh() 方法
Spring IOC 容器的 refresh() 方法是容器啟動的核心入口,包含 12 個標準步驟,負責完成從配置加載到 Bean 實例化的全流程。
整體流程是什么
refresh() 方法在 AbstractApplicationContext 中定義,采用模板方法模式,確保容器初始化過程線程安全。12 個步驟按順序執(zhí)行:
- 準備階段:prepareRefresh() 記錄啟動時間、設(shè)置活躍標志。
- 工廠獲取:obtainFreshBeanFactory() 創(chuàng)建或刷新 BeanFactory。
- 工廠配置:prepareBeanFactory() 設(shè)置類加載器、表達式解析器等基礎(chǔ)設(shè)施。
- 后置處理:postProcessBeanFactory() 留給子類擴展的空實現(xiàn)。
- 處理器調(diào)用:invokeBeanFactoryPostProcessors() 執(zhí)行配置類后置處理器。
- 處理器注冊:registerBeanPostProcessors() 注冊 Bean 實例化前后攔截器。
- 消息源初始化:initMessageSource() 處理國際化資源。
- 事件廣播器:initApplicationEventMulticaster() 建立事件發(fā)布機制。
- 子類擴展:onRefresh() 模板方法供 Web 容器等初始化特定功能。
- 監(jiān)聽器注冊:registerListeners() 添加應(yīng)用事件監(jiān)聽器。
- Bean 初始化:finishBeanFactoryInitialization() 實例化所有非懶加載單例。
- 刷新完成:finishRefresh() 發(fā)布容器刷新完成事件。
Spring IOC 容器 refresh() 方法的 12 個標準步驟逐行解析
標簽:Spring | IOC | refresh | Bean 生命周期
一、問題引入
// 我們每天都在用的 Spring Boot 啟動 SpringApplication.run(MyApp.class, args); // 其底層最終調(diào)用的是: ConfigurableApplicationContext context = new AnnotationConfigApplicationContext(); context.refresh(); // ← 一切魔法從這里開始
refresh() 方法是 Spring Framework 最核心的方法之一。從配置文件加載、Bean 定義注冊到單例預(yù)實例化,整個 Spring 容器的生命周期都在這里完成。本文逐行解析 refresh() 的 12 個標準步驟。
二、refresh()方法全貌
// org.springframework.context.support.AbstractApplicationContext
@Override
public void refresh() throws BeansException, IllegalStateException {
synchronized (this.startupShutdownMonitor) {
StartupStep contextRefresh = this.applicationStartup.start("spring.context.refresh");
// 步驟 1: 準備刷新
prepareRefresh();
// 步驟 2: 獲取/刷新 BeanFactory
ConfigurableListableBeanFactory beanFactory = obtainFreshBeanFactory();
// 步驟 3: 準備 BeanFactory
prepareBeanFactory(beanFactory);
try {
// 步驟 4: 子類擴展的 BeanFactory 后處理
postProcessBeanFactory(beanFactory);
StartupStep beanPostProcess = this.applicationStartup.start(
"spring.context.beans.post-process");
// 步驟 5: 執(zhí)行 BeanFactoryPostProcessor
invokeBeanFactoryPostProcessors(beanFactory);
// 步驟 6: 注冊 BeanPostProcessor
registerBeanPostProcessors(beanFactory);
beanPostProcess.end();
// 步驟 7: 初始化消息源
initMessageSource();
// 步驟 8: 初始化事件廣播器
initApplicationEventMulticaster();
// 步驟 9: 子類擴展的初始化邏輯
onRefresh();
// 步驟 10: 注冊監(jiān)聽器
registerListeners();
// 步驟 11: 實例化所有非延遲單例 Bean
finishBeanFactoryInitialization(beanFactory);
// 步驟 12: 完成刷新,發(fā)布事件
finishRefresh();
}
// ... 異常處理
}
}三、12 步驟逐行解析
步驟 1:prepareRefresh()—— 準備刷新
protected void prepareRefresh() {
// 記錄啟動時間
this.startupDate = System.currentTimeMillis();
this.closed.set(false);
this.active.set(true);
// 初始化屬性源(如 @PropertySource 指定的配置文件)
initPropertySources();
// 驗證必需的環(huán)境變量是否都存在
getEnvironment().validateRequiredProperties();
// 初始化早期應(yīng)用監(jiān)聽器
if (this.earlyApplicationListeners == null) {
this.earlyApplicationListeners = new LinkedHashSet<>(this.applicationListeners);
}
}核心職責:環(huán)境準備 + 狀態(tài)切換 + 屬性驗證。
步驟 2:obtainFreshBeanFactory()—— 獲取 BeanFactory
protected ConfigurableListableBeanFactory obtainFreshBeanFactory() {
// 子類實現(xiàn):創(chuàng)建或刷新內(nèi)部的 BeanFactory
refreshBeanFactory();
// 返回 freshly created BeanFactory
return getBeanFactory();
}
AnnotationConfigApplicationContext 的實現(xiàn):
@Override
protected final void refreshBeanFactory() throws BeansException {
// 如果有舊的 BeanFactory,銷毀所有 Bean 并關(guān)閉
if (hasBeanFactory()) {
destroyBeans();
closeBeanFactory();
}
try {
// 創(chuàng)建新的 DefaultListableBeanFactory
DefaultListableBeanFactory beanFactory = createBeanFactory();
beanFactory.setSerializationId(getId());
customizeBeanFactory(beanFactory);
// 加載 Bean 定義(@Configuration 類解析)
loadBeanDefinitions(beanFactory);
this.beanFactory = beanFactory;
} catch (IOException ex) {
throw new ApplicationContextException("I/O error parsing bean definition source", ex);
}
}DefaultListableBeanFactory 是 Spring 最核心的 BeanFactory 實現(xiàn):
public class DefaultListableBeanFactory extends AbstractAutowireCapableBeanFactory
implements ConfigurableListableBeanFactory, BeanDefinitionRegistry {
// Bean 定義的注冊表:key=beanName, value=BeanDefinition
private final Map<String, BeanDefinition> beanDefinitionMap = new ConcurrentHashMap<>(256);
// 單例 Bean 的緩存池
private final Map<String, Object> singletonObjects = new ConcurrentHashMap<>(256);
// 按類型索引的 Bean 名稱
private final Map<Class<?>, String[]> allBeanNamesByType = new ConcurrentHashMap<>(64);
}步驟 3:prepareBeanFactory()—— 準備 BeanFactory
protected void prepareBeanFactory(ConfigurableListableBeanFactory beanFactory) {
// 設(shè)置類加載器
beanFactory.setBeanClassLoader(getClassLoader());
// 添加 SpEL 表達式解析器(@Value("${app.name}") 的解析)
beanFactory.setBeanExpressionResolver(new StandardBeanExpressionResolver());
// 添加屬性編輯器注冊器(String → Date 等類型轉(zhuǎn)換)
beanFactory.addPropertyEditorRegistrar(new ResourceEditorRegistrar(this, getEnvironment()));
// 添加 BeanPostProcessor:ApplicationContextAwareProcessor
// 處理 Aware 接口:ApplicationContextAware, EnvironmentAware, ResourceLoaderAware
beanFactory.addBeanPostProcessor(new ApplicationContextAwareProcessor(this));
// 忽略以下依賴接口的自動裝配(由 ApplicationContextAwareProcessor 處理)
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);
// 注冊早期后置處理器:檢測 ApplicationListener 類型的 Bean
beanFactory.addBeanPostProcessor(new ApplicationListenerDetector(this));
// 檢測 LoadTimeWeaver(AOP 加載時織入)
if (beanFactory.containsBean(LOAD_TIME_WEAVER_BEAN_NAME)) {
beanFactory.addBeanPostProcessor(new LoadTimeWeaverAwareProcessor(beanFactory));
beanFactory.setTempClassLoader(new ContextTypeMatchClassLoader(beanFactory.getBeanClassLoader()));
}
// 注冊默認環(huán)境 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());
}
}核心職責:注冊內(nèi)置的 BeanPostProcessor + 配置自動裝配規(guī)則 + 注冊環(huán)境 Bean。
步驟 4:postProcessBeanFactory()—— BeanFactory 后處理(子類擴展)
// AbstractApplicationContext 中為空實現(xiàn),子類可覆蓋
protected void postProcessBeanFactory(ConfigurableListableBeanFactory beanFactory) {
}
// AnnotationConfigApplicationContext 的擴展:
@Override
protected void postProcessBeanFactory(ConfigurableListableBeanFactory beanFactory) {
super.postProcessBeanFactory(beanFactory);
// 添加 ConfigurationClassPostProcessor 的回調(diào)
if (this.basePackages != null && this.basePackages.length > 0) {
// 掃描 @Component 類并注冊 Bean 定義
this.scanner.scan(this.basePackages);
}
if (!this.annotatedClasses.isEmpty()) {
// 注冊 @Configuration 類
this.reader.register(ClassUtils.toClassArray(this.annotatedClasses));
}
}步驟 5:invokeBeanFactoryPostProcessors()—— 執(zhí)行 BeanFactory 后置處理器
這是最重要的步驟之一——處理 @Configuration 類、解析 @Bean 方法、處理 @PropertySource/@ComponentScan/@Import。
protected void invokeBeanFactoryPostProcessors(ConfigurableListableBeanFactory beanFactory) {
PostProcessorRegistrationDelegate.invokeBeanFactoryPostProcessors(beanFactory,
getBeanFactoryPostProcessors());
}
處理順序(嚴格按優(yōu)先級):
1. BeanDefinitionRegistryPostProcessor (繼承 BeanFactoryPostProcessor)
└─ ConfigurationClassPostProcessor ← 最重要!處理 @Configuration
├─ 解析 @ComponentScan → 掃描包下的 @Component
├─ 解析 @Import → 處理 @EnableAutoConfiguration
├─ 解析 @ImportResource → 加載 XML 配置
├─ 解析 @Bean → 注冊方法返回值為 Bean
└─ 解析 @PropertySource → 加載屬性文件
2. 常規(guī)的 BeanFactoryPostProcessor
└─ PropertySourcesPlaceholderConfigurer ← 處理 ${...} 占位符ConfigurationClassPostProcessor 的核心流程:
public class ConfigurationClassPostProcessor implements BeanDefinitionRegistryPostProcessor {
@Override
public void postProcessBeanDefinitionRegistry(BeanDefinitionRegistry registry) {
// 1. 從注冊表中找出所有 @Configuration 類
List<BeanDefinitionHolder> configCandidates = new ArrayList<>();
for (String beanName : registry.getBeanDefinitionNames()) {
BeanDefinition beanDef = registry.getBeanDefinition(beanName);
if (ConfigurationClassUtils.checkConfigurationClassCandidate(beanDef, this.metadataReaderFactory)) {
configCandidates.add(new BeanDefinitionHolder(beanDef, beanName));
}
}
// 2. 解析每個 @Configuration 類
ConfigurationClassParser parser = new ConfigurationClassParser(...);
parser.parse(configCandidates);
// 3. 讀取解析結(jié)果,注冊新的 Bean 定義
Set<ConfigurationClass> configClasses = new LinkedHashSet<>(parser.getConfigurationClasses());
ConfigurationClassBeanDefinitionReader reader = new ConfigurationClassBeanDefinitionReader(...);
reader.loadBeanDefinitions(configClasses);
}
}步驟 6:registerBeanPostProcessors()—— 注冊 Bean 后置處理器
protected void registerBeanPostProcessors(ConfigurableListableBeanFactory beanFactory) {
PostProcessorRegistrationDelegate.registerBeanPostProcessors(beanFactory, this);
}
注冊順序(按 Ordered/PriorityOrdered 排序):
1. PriorityOrdered 的 BeanPostProcessor └─ AutowiredAnnotationBeanPostProcessor ← 處理 @Autowired └─ CommonAnnotationBeanPostProcessor ← 處理 @PostConstruct, @PreDestroy, @Resource 2. Ordered 的 BeanPostProcessor 3. 普通的 BeanPostProcessor └─ AsyncAnnotationBeanPostProcessor ← 處理 @Async └─ ScheduledAnnotationBeanPostProcessor ← 處理 @Scheduled └─ TransactionProxyFactoryBean ← 處理 @Transactional └─ AOP 相關(guān)的 BeanPostProcessor ← 處理 @Aspect 4. ApplicationListenerDetector(內(nèi)部使用)
AutowiredAnnotationBeanPostProcessor 的注入時機:
public class AutowiredAnnotationBeanPostProcessor implements InstantiationAwareBeanPostProcessor {
@Override
public PropertyValues postProcessProperties(PropertyValues pvs, Object bean, String beanName) {
// 1. 查找 @Autowired 標注的字段/方法
InjectionMetadata metadata = findAutowiringMetadata(beanName, bean.getClass(), pvs);
// 2. 執(zhí)行注入
metadata.inject(bean, beanName, pvs);
return pvs;
}
}步驟 7:initMessageSource()—— 初始化消息源
protected void initMessageSource() {
ConfigurableListableBeanFactory beanFactory = getBeanFactory();
if (beanFactory.containsLocalBean(MESSAGE_SOURCE_BEAN_NAME)) {
// 用戶自定義了 MessageSource
this.messageSource = beanFactory.getBean(MESSAGE_SOURCE_BEAN_NAME, MessageSource.class);
} else {
// 使用默認的 DelegatingMessageSource
DelegatingMessageSource dms = new DelegatingMessageSource();
dms.setParentMessageSource(getInternalParentMessageSource());
this.messageSource = dms;
beanFactory.registerSingleton(MESSAGE_SOURCE_BEAN_NAME, this.messageSource);
}
}步驟 8:initApplicationEventMulticaster()—— 初始化事件廣播器
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 {
// 默認使用 SimpleApplicationEventMulticaster
this.applicationEventMulticaster = new SimpleApplicationEventMulticaster(beanFactory);
beanFactory.registerSingleton(APPLICATION_EVENT_MULTICASTER_BEAN_NAME,
this.applicationEventMulticaster);
}
}
步驟 9:onRefresh()—— 子類擴展(創(chuàng)建內(nèi)嵌 Web 服務(wù)器)
// AbstractApplicationContext 中為空實現(xiàn)
protected void onRefresh() throws BeansException {
}
// ServletWebServerApplicationContext 的擴展:
@Override
protected void onRefresh() {
super.onRefresh();
try {
// 創(chuàng)建內(nèi)嵌 Tomcat/Jetty/Undertow
createWebServer();
} catch (Throwable ex) {
throw new ApplicationContextException("Unable to start web server", ex);
}
}
private void createWebServer() {
WebServer webServer = this.webServer;
ServletContext servletContext = getServletContext();
if (webServer == null && servletContext == null) {
// 從 BeanFactory 獲取 WebServerFactory
ServletWebServerFactory factory = getWebServerFactory();
// 創(chuàng)建 WebServer(如 TomcatWebServer)
this.webServer = factory.getWebServer(getSelfInitializer());
}
}Spring Boot 內(nèi)嵌 Tomcat 的創(chuàng)建就是在這里完成的!
步驟 10:registerListeners()—— 注冊監(jiān)聽器
protected void registerListeners() {
// 注冊靜態(tài)指定的監(jiān)聽器
for (ApplicationListener<?> listener : getApplicationListeners()) {
getApplicationEventMulticaster().addApplicationListener(listener);
}
// 從 BeanFactory 獲取所有 ApplicationListener 類型的 Bean
String[] listenerBeanNames = getBeanFactoryNamesForType(ApplicationListener.class, true, false);
for (String listenerBeanName : listenerBeanNames) {
getApplicationEventMulticaster().addApplicationListenerBean(listenerBeanName);
}
// 發(fā)布早期累積的事件
Set<ApplicationEvent> earlyEventsToProcess = this.earlyApplicationEvents;
this.earlyApplicationEvents = null;
if (!CollectionUtils.isEmpty(earlyEventsToProcess)) {
for (ApplicationEvent earlyEvent : earlyEventsToProcess) {
getApplicationEventMulticaster().multicastEvent(earlyEvent);
}
}
}步驟 11:finishBeanFactoryInitialization()—— 實例化所有非延遲單例 Bean
protected void finishBeanFactoryInitialization(ConfigurableListableBeanFactory beanFactory) {
// 轉(zhuǎn)換服務(wù)(String → Integer 等類型轉(zhuǎn)換)
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);
// 凍結(jié)配置(不允許再修改 Bean 定義)
beanFactory.freezeConfiguration();
// ★★★ 實例化所有非延遲單例 Bean ★★★
beanFactory.preInstantiateSingletons();
}preInstantiateSingletons() 是核心:
@Override
public void preInstantiateSingletons() throws BeansException {
List<String> beanNames = new ArrayList<>(this.beanDefinitionNames);
// 觸發(fā)所有非延遲單例 Bean 的實例化
for (String beanName : beanNames) {
RootBeanDefinition bd = getMergedLocalBeanDefinition(beanName);
// 非抽象 && 單例 && 非延遲初始化
if (!bd.isAbstract() && bd.isSingleton() && !bd.isLazyInit()) {
if (isFactoryBean(beanName)) {
// FactoryBean 特殊處理
Object bean = getBean(FACTORY_BEAN_PREFIX + beanName);
} else {
// ★ 普通 Bean 的獲取 → 觸發(fā)創(chuàng)建
getBean(beanName);
}
}
}
// 觸發(fā) SmartInitializingSingleton 回調(diào)
for (String beanName : beanNames) {
Object singletonInstance = getSingleton(beanName);
if (singletonInstance instanceof SmartInitializingSingleton) {
((SmartInitializingSingleton) singletonInstance).afterSingletonsInstantiated();
}
}
}步驟 12:finishRefresh()—— 完成刷新
protected void finishRefresh() {
// 清除上下文級資源緩存
clearResourceCaches();
// 初始化 LifecycleProcessor
initLifecycleProcessor();
// 啟動所有實現(xiàn)了 Lifecycle 接口的 Bean
getLifecycleProcessor().onRefresh();
// ★ 發(fā)布 ContextRefreshedEvent 事件 ★
publishEvent(new ContextRefreshedEvent(this));
// LiveBeansView MBean 注冊(JMX 監(jiān)控)
LiveBeansView.registerApplicationContext(this);
}ContextRefreshedEvent 是應(yīng)用啟動完成的標志,很多框架(如 Dubbo)監(jiān)聽此事件完成服務(wù)暴露。
四、12 步驟總結(jié)圖
┌─────────────────────────────────────────────────────┐
│ refresh() 12 步驟 │
├─────────────────────────────────────────────────────┤
│ 1. prepareRefresh() 環(huán)境準備 + 狀態(tài)校驗 │
│ 2. obtainFreshBeanFactory() 創(chuàng)建 BeanFactory │
│ 3. prepareBeanFactory() 注冊內(nèi)置 BPP │
│ 4. postProcessBeanFactory() 子類擴展(掃描) │
│ 5. invokeBeanFactoryPostProcessors() @Configuration │
│ 6. registerBeanPostProcessors() 注冊 @Autowired/AOP │
│ 7. initMessageSource() 國際化 │
│ 8. initApplicationEventMulticaster() 事件廣播器 │
│ 9. onRefresh() 子類(創(chuàng)建 WebServer) │
│ 10. registerListeners() 注冊 @EventListener │
│ 11. finishBeanFactoryInitialization() 實例化單例 │
│ 12. finishRefresh() 發(fā)布刷新完成事件 │
└─────────────────────────────────────────────────────┘
↓
Application Ready!到此這篇關(guān)于Spring IOC 容器 refresh() 方法的文章就介紹到這了,更多相關(guān)Spring IOC 容器 refresh() 內(nèi)容請搜索腳本之家以前的文章或繼續(xù)瀏覽下面的相關(guān)文章希望大家以后多多支持腳本之家!
相關(guān)文章
為什么wait和notify必須放在synchronized中使用
這篇文章主要介紹了為什么wait和notify必須放在synchronized中使用,文章圍繞主題的相關(guān)問題展開詳細介紹,具有一定的參考價值,需要的小伙伴可以參考以參考一下2022-05-05
使用jackson實現(xiàn)對象json之間的相互轉(zhuǎn)換(spring boot)
這篇文章主要介紹了使用jackson實現(xiàn)對象json之間的相互轉(zhuǎn)換(spring boot),具有很好的參考價值,希望對大家有所幫助。如有錯誤或未考慮完全的地方,望不吝賜教2021-09-09
Java復(fù)制一個對象并且不想復(fù)制其中的空值屬性問題
這篇文章主要介紹了Java復(fù)制一個對象并且不想復(fù)制其中的空值屬性問題,具有很好的參考價值,希望對大家有所幫助,如有錯誤或未考慮完全的地方,望不吝賜教2023-08-08
Hibernate框架數(shù)據(jù)分頁技術(shù)實例分析
這篇文章主要介紹了Hibernate框架數(shù)據(jù)分頁技術(shù),結(jié)合實例形式分析了Hibernate框架實現(xiàn)數(shù)據(jù)分頁的原理,步驟與相關(guān)實現(xiàn)技巧,需要的朋友可以參考下2016-03-03

