深度解析Spring Bean生命周期的各個(gè)階段
概述
Spring Bean的生命周期是Spring框架的核心概念之一,理解Bean從創(chuàng)建到銷毀的整個(gè)過程對(duì)于開發(fā)高質(zhì)量的Spring應(yīng)用程序至關(guān)重要。本文將詳細(xì)梳理Spring Bean生命周期的各個(gè)階段,并通過代碼示例展示每個(gè)關(guān)鍵節(jié)點(diǎn)。
Spring Bean生命周期階段
1. 實(shí)例化階段
Spring容器通過構(gòu)造函數(shù)或工廠方法創(chuàng)建Bean實(shí)例
public class ExampleBean {
public ExampleBean() {
System.out.println("1. Bean實(shí)例化 - 構(gòu)造函數(shù)執(zhí)行");
}
}2. 屬性賦值階段
Spring容器注入Bean的屬性和依賴
public class ExampleBean {
private String name;
private AnotherBean anotherBean;
// Setter方法用于屬性注入
public void setName(String name) {
System.out.println("2. 屬性注入 - name: " + name);
this.name = name;
}
public void setAnotherBean(AnotherBean anotherBean) {
System.out.println("2. 依賴注入 - anotherBean");
this.anotherBean = anotherBean;
}
}3. Aware接口回調(diào)階段
Bean實(shí)現(xiàn)Aware接口獲取容器資源
public class ExampleBean implements BeanNameAware, BeanFactoryAware, ApplicationContextAware {
@Override
public void setBeanName(String name) {
System.out.println("3. BeanNameAware - Bean名稱: " + name);
}
@Override
public void setBeanFactory(BeanFactory beanFactory) throws BeansException {
System.out.println("3. BeanFactoryAware - BeanFactory注入");
}
@Override
public void setApplicationContext(ApplicationContext applicationContext) throws BeansException {
System.out.println("3. ApplicationContextAware - ApplicationContext注入");
}
}4. BeanPostProcessor前置處理
BeanPostProcessor的postProcessBeforeInitialization方法
@Component
public class CustomBeanPostProcessor implements BeanPostProcessor {
@Override
public Object postProcessBeforeInitialization(Object bean, String beanName) throws BeansException {
if (bean instanceof ExampleBean) {
System.out.println("4. BeanPostProcessor前置處理 - " + beanName);
}
return bean;
}
}5. 初始化階段
@PostConstruct注解方法
public class ExampleBean {
@PostConstruct
public void postConstruct() {
System.out.println("5.1 @PostConstruct方法執(zhí)行");
}
}InitializingBean接口
public class ExampleBean implements InitializingBean {
@Override
public void afterPropertiesSet() throws Exception {
System.out.println("5.2 InitializingBean.afterPropertiesSet()執(zhí)行");
}
}自定義init方法
public class ExampleBean {
public void customInit() {
System.out.println("5.3 自定義init方法執(zhí)行");
}
}
// 配置類中指定init方法
@Configuration
public class AppConfig {
@Bean(initMethod = "customInit")
public ExampleBean exampleBean() {
return new ExampleBean();
}
}6. BeanPostProcessor后置處理
BeanPostProcessor的postProcessAfterInitialization方法
@Component
public class CustomBeanPostProcessor implements BeanPostProcessor {
@Override
public Object postProcessAfterInitialization(Object bean, String beanName) throws BeansException {
if (bean instanceof ExampleBean) {
System.out.println("6. BeanPostProcessor后置處理 - " + beanName);
}
return bean;
}
}7. Bean使用階段
Bean完全初始化,可供應(yīng)用程序使用
@Service
public class BusinessService {
private final ExampleBean exampleBean;
public BusinessService(ExampleBean exampleBean) {
this.exampleBean = exampleBean;
}
public void doBusiness() {
System.out.println("7. Bean使用階段 - 執(zhí)行業(yè)務(wù)邏輯");
}
}8. 銷毀階段
@PreDestroy注解方法
public class ExampleBean {
@PreDestroy
public void preDestroy() {
System.out.println("8.1 @PreDestroy方法執(zhí)行");
}
}DisposableBean接口
public class ExampleBean implements DisposableBean {
@Override
public void destroy() throws Exception {
System.out.println("8.2 DisposableBean.destroy()執(zhí)行");
}
}自定義destroy方法
public class ExampleBean {
public void customDestroy() {
System.out.println("8.3 自定義destroy方法執(zhí)行");
}
}
// 配置類中指定destroy方法
@Configuration
public class AppConfig {
@Bean(destroyMethod = "customDestroy")
public ExampleBean exampleBean() {
return new ExampleBean();
}
}完整示例代碼
1. 定義Bean類
import org.springframework.beans.factory.*;
import org.springframework.context.ApplicationContext;
import org.springframework.context.ApplicationContextAware;
import javax.annotation.PostConstruct;
import javax.annotation.PreDestroy;
public class LifecycleBean implements BeanNameAware, BeanFactoryAware,
ApplicationContextAware, InitializingBean, DisposableBean {
private String name;
private AnotherBean anotherBean;
public LifecycleBean() {
System.out.println("1. 構(gòu)造函數(shù)執(zhí)行 - Bean實(shí)例化");
}
public void setName(String name) {
System.out.println("2. 屬性注入 - name: " + name);
this.name = name;
}
public void setAnotherBean(AnotherBean anotherBean) {
System.out.println("2. 依賴注入 - anotherBean");
this.anotherBean = anotherBean;
}
@Override
public void setBeanName(String name) {
System.out.println("3. BeanNameAware - Bean名稱: " + name);
}
@Override
public void setBeanFactory(BeanFactory beanFactory) throws BeansException {
System.out.println("3. BeanFactoryAware - BeanFactory注入");
}
@Override
public void setApplicationContext(ApplicationContext applicationContext) throws BeansException {
System.out.println("3. ApplicationContextAware - ApplicationContext注入");
}
@PostConstruct
public void postConstruct() {
System.out.println("5.1 @PostConstruct方法執(zhí)行");
}
@Override
public void afterPropertiesSet() throws Exception {
System.out.println("5.2 InitializingBean.afterPropertiesSet()執(zhí)行");
}
public void customInit() {
System.out.println("5.3 自定義init方法執(zhí)行");
}
public void doSomething() {
System.out.println("7. Bean使用階段 - 執(zhí)行業(yè)務(wù)方法");
}
@PreDestroy
public void preDestroy() {
System.out.println("8.1 @PreDestroy方法執(zhí)行");
}
@Override
public void destroy() throws Exception {
System.out.println("8.2 DisposableBean.destroy()執(zhí)行");
}
public void customDestroy() {
System.out.println("8.3 自定義destroy方法執(zhí)行");
}
}2. 配置BeanPostProcessor
import org.springframework.beans.BeansException;
import org.springframework.beans.factory.config.BeanPostProcessor;
import org.springframework.stereotype.Component;
@Component
public class CustomBeanPostProcessor implements BeanPostProcessor {
@Override
public Object postProcessBeforeInitialization(Object bean, String beanName) throws BeansException {
if (bean instanceof LifecycleBean) {
System.out.println("4. BeanPostProcessor前置處理 - " + beanName);
}
return bean;
}
@Override
public Object postProcessAfterInitialization(Object bean, String beanName) throws BeansException {
if (bean instanceof LifecycleBean) {
System.out.println("6. BeanPostProcessor后置處理 - " + beanName);
}
return bean;
}
}3. 配置類
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;
@Configuration
public class AppConfig {
@Bean(initMethod = "customInit", destroyMethod = "customDestroy")
public LifecycleBean lifecycleBean() {
LifecycleBean bean = new LifecycleBean();
bean.setName("示例Bean");
return bean;
}
@Bean
public AnotherBean anotherBean() {
return new AnotherBean();
}
}4. 測試類
import org.springframework.context.annotation.AnnotationConfigApplicationContext;
public class LifecycleTest {
public static void main(String[] args) {
System.out.println("Spring容器啟動(dòng)...");
AnnotationConfigApplicationContext context =
new AnnotationConfigApplicationContext(AppConfig.class);
System.out.println("\n獲取Bean并執(zhí)行業(yè)務(wù)方法...");
LifecycleBean bean = context.getBean(LifecycleBean.class);
bean.doSomething();
System.out.println("\nSpring容器關(guān)閉...");
context.close();
System.out.println("程序結(jié)束");
}
}生命周期流程圖
Bean生命周期完整流程:
1. 實(shí)例化 → 2. 屬性賦值 → 3. Aware接口回調(diào) → 4. BeanPostProcessor前置處理 →
5. 初始化(@PostConstruct → InitializingBean → 自定義init) → 6. BeanPostProcessor后置處理 →
7. Bean就緒可用 → 8. 銷毀(@PreDestroy → DisposableBean → 自定義destroy)
總結(jié)
Spring Bean的生命周期是一個(gè)復(fù)雜但有序的過程,理解每個(gè)階段的執(zhí)行順序和用途對(duì)于:
- 調(diào)試和問題排查:能夠快速定位Bean初始化相關(guān)的問題
- 擴(kuò)展功能:通過BeanPostProcessor等機(jī)制擴(kuò)展Spring功能
- 資源管理:正確管理數(shù)據(jù)庫連接、線程池等資源
- 性能優(yōu)化:合理使用各種初始化機(jī)制提升應(yīng)用性能
到此這篇關(guān)于Spring Bean生命周期全面解析的文章就介紹到這了,更多相關(guān)Spring Bean生命周期內(nèi)容請(qǐng)搜索腳本之家以前的文章或繼續(xù)瀏覽下面的相關(guān)文章希望大家以后多多支持腳本之家!
相關(guān)文章
Java并發(fā)編程:volatile關(guān)鍵字詳細(xì)解析
這篇文章主要介紹了Java并發(fā)編程:volatile關(guān)鍵字詳細(xì)解析,對(duì)學(xué)習(xí)volatile關(guān)鍵字有一定的認(rèn)識(shí),有需要的可以了解一下。2016-11-11
Maven在Windows中的配置以及IDE中的項(xiàng)目創(chuàng)建實(shí)例
下面小編就為大家?guī)硪黄狹aven在Windows中的配置以及IDE中的項(xiàng)目創(chuàng)建實(shí)例。小編覺得挺不錯(cuò)的,現(xiàn)在就分享給大家,也給大家做個(gè)參考。一起跟隨小編過來看看吧2017-09-09
Java實(shí)現(xiàn)快速排序算法(Quicktsort)
這篇文章主要介紹了Java實(shí)現(xiàn)快速排序算法(Quicktsort),有需要的朋友可以參考一下2013-12-12
Netty啟動(dòng)流程注冊(cè)多路復(fù)用源碼解析
這篇文章主要介紹了Netty啟動(dòng)流程注冊(cè)多路復(fù)用源碼分析,繼續(xù)分析channel是如何注冊(cè)到selector中的,有需要的朋友可以借鑒參考下,希望能夠有所幫助2022-03-03
基于Java代碼實(shí)現(xiàn)支付充值的通用流程
本文給大家分享一段java核心代碼實(shí)現(xiàn)支付充值的通用流程,非常不錯(cuò),具有參考借鑒價(jià)值,感興趣的朋友一起看看吧2016-05-05
修改jar包package目錄結(jié)構(gòu)操作方法
這篇文章主要介紹了修改jar包package目錄結(jié)構(gòu)操作方法,本文給大家介紹的非常詳細(xì),具有一定的參考借鑒價(jià)值 ,需要的朋友可以參考下2019-07-07
SpringBoot集成FastDFS依賴實(shí)現(xiàn)文件上傳的示例
這篇文章主要介紹了SpringBoot集成FastDFS依賴實(shí)現(xiàn)文件上傳,文中通過示例代碼介紹的非常詳細(xì),對(duì)大家的學(xué)習(xí)或者工作具有一定的參考學(xué)習(xí)價(jià)值,需要的朋友們下面隨著小編來一起學(xué)習(xí)學(xué)習(xí)吧2021-05-05

