面試官:Spring Bean 的生命週期都不會,你走吧下一位

面試官:看你簡歷上寫了不少Spring相關的項目經驗,那我們來聊聊Spring的核心概念吧。你能詳細説説Spring Bean的生命週期嗎?

:Bean的生命週期?這個...我知道有創建、初始化、銷燬這些階段,但具體的細節和順序我有點記不清了...

面試官:Spring Bean 的生命週期都不會,你走吧下一位_項目

解析答案

Spring Bean 生命週期的完整旅程

Spring Bean 的生命週期就像是一個人的一生,從出生(實例化)到成長(初始化),再到工作(使用),最後到退休(銷燬)。讓我們一起來探索這個精彩的過程:

第一階段:Bean 的誕生 - 實例化過程

1. BeanDefinition 的加載 Spring 首先讀取配置信息(XML、註解或Java配置),解析成 BeanDefinition 對象。這就像是給 Bean 辦理"出生證明"。

2. 構造方法的推斷 如果有多個構造方法,Spring 會智能地選擇最合適的那個:

  • 優先選擇帶有 @Autowired 註解的構造方法
  • 如果沒有註解,選擇無參構造方法
  • 如果只有一個有參構造方法,直接使用它

3. 對象的實例化 通過反射機制創建 Bean 的實例,這相當於"新生兒"的誕生。

第二階段:Bean 的成長 - 初始化過程

4. 屬性注入(依賴注入) Spring 自動為加了 @Autowired@Value 等註解的屬性賦值:

@Component
public class UserService {
    @Autowired
    private UserRepository userRepository;  // Spring 會自動注入
    @Value("${app.name}")
    private String appName;  // 配置屬性注入
}

5. Aware 接口回調 如果 Bean 實現了特定的 Aware 接口,Spring 會回調相應方法:

  • BeanNameAware:感知自己的 Bean 名稱
  • BeanFactoryAware:感知所在的 Bean 工廠
  • ApplicationContextAware:感知應用上下文

6. BeanPostProcessor 的前置處理 這是 Spring 提供的重要擴展點,可以在初始化前進行自定義處理:

@Component
public class CustomBeanPostProcessor implements BeanPostProcessor {
    @Override
    public Object postProcessBeforeInitialization(Object bean, String beanName) {
        System.out.println("初始化前處理: " + beanName);
        return bean;
    }
}

7. 初始化方法調用 Spring 會按順序調用初始化方法:

  • 首先調用 @PostConstruct 註解的方法
  • 然後調用 InitializingBean 接口的 afterPropertiesSet() 方法
  • 最後調用 XML 中配置的 init-method 方法

8. BeanPostProcessor 的後置處理 這是 AOP 代理創建的關鍵時機:

@Component
public class CustomBeanPostProcessor implements BeanPostProcessor {
    @Override
    public Object postProcessAfterInitialization(Object bean, String beanName) {
        // 這裏可能會創建 AOP 代理對象
        System.out.println("初始化後處理: " + beanName);
        return bean;
    }
}
第三階段:Bean 的輝煌 - 使用階段

9. 加入單例池 如果是單例 Bean,Spring 會將其放入單例池中,供後續使用。

10. 正式服役 此時 Bean 已經完全準備好,可以被應用程序正常使用了。

第四階段:Bean 的謝幕 - 銷燬過程

11. 容器關閉時的清理 當 Spring 容器關閉時,會按順序調用銷燬方法:

  • 首先調用 @PreDestroy 註解的方法
  • 然後調用 DisposableBean 接口的 destroy() 方法
  • 最後調用 XML 中配置的 destroy-method 方法

Bean 作用域:不同的"人生軌跡"

不同的 Bean 作用域決定了它們不同的"人生軌跡":

Singleton(單例)- 一生只愛一人

面試官:Spring Bean 的生命週期都不會,你走吧下一位_生命週期_02

@Component
@Scope("singleton")
public class SingletonBean {
    // 整個應用中只有一個實例
}
  • Spring 默認的作用域
  • 整個應用生命週期內共享同一個實例
  • 適合無狀態的 Bean,如 Service、Repository
Prototype(原型)- 每次都是新的開始
@Component
@Scope("prototype")
public class PrototypeBean {
    // 每次獲取都是新的實例
}
  • 每次 getBean() 都返回新的實例
  • 適合有狀態的 Bean
  • Spring 不管理完整的生命週期,只負責創建
Request(請求)- 一次請求一次人生
@Component
@Scope("request")
public class RequestBean {
    // 每個 HTTP 請求都有新的實例
}
  • 每個 HTTP 請求創建新的實例
  • 請求結束時自動銷燬
  • 適合存儲請求相關數據
Session(會話)- 一次會話一段旅程
@Component
@Scope("session")
public class SessionBean {
    // 每個用户會話都有新的實例
}
  • 每個用户會話創建新的實例
  • 會話結束時自動銷燬
  • 適合存儲用户會話數據

實際開發中的最佳實踐

1. 選擇合適的初始化時機
@Component
public class CacheService {
    // 輕量級初始化放在構造方法
    public CacheService() {
        // 初始化基本數據結構
    }
    
    // 重量級初始化放在 @PostConstruct
    @PostConstruct
    public void init() {
        // 加載緩存數據,建立網絡連接等
    }
}
2. 正確處理異常
@Component
public class CriticalService {
    @PostConstruct
    public void init() {
        try {
            // 關鍵初始化邏輯
        } catch (Exception e) {
            // 記錄日誌並拋出異常,讓容器知道初始化失敗
            throw new RuntimeException("初始化失敗", e);
        }
    }
}
3. 避免循環依賴
@Service
public class ServiceA {
    // 構造方法注入可以避免某些循環依賴問題
    private final ServiceB serviceB;
    
    public ServiceA(ServiceB serviceB) {
        this.serviceB = serviceB;
    }
}

歡迎交流

通過本文的詳細講解,相信你已經對 Spring Bean 的生命週期有了全面深入的理解。掌握這些知識不僅有助於面試,更能幫助你在實際開發中更好地使用 Spring 框架。以下幾個問題可以幫助你進一步思考:

  1. 在微服務架構中,Bean 的生命週期管理有什麼特殊的考慮?
  2. 如何利用 BeanPostProcessor 實現自定義的業務邏輯?
  3. 在雲原生環境下,Bean 的銷燬過程需要注意哪些問題?

歡迎在評論區分享你的見解和實踐經驗!

面試官:Spring Bean 的生命週期都不會,你走吧下一位_八股_03

項目

項目適用人羣:做課設、畢設的小夥伴、只學習了後端(或者前端),但想要自己做項目寫在簡歷上,這三個項目可以作為拓展點。

項目有多線程、事務管理、Redis 緩存、買票問題、線程池、大模型調用等可以寫的點,而且體驗會發現接口響應速度是很快的,功能也比較實用,想要參與開源項目的 Commiter 也可以提出。

智能 AI 旅遊推薦平台:https://github.com/luoye6/vue3_tourism_frontend

智能 AI 校園二手交易平台:https://github.com/luoye6/vue3_trade_frontend

GPT 智能圖書館:https://github.com/luoye6/Vue_BookManageSystem

歡迎關注上方公眾號!感謝支持!一起進步,共勉!