1. 程式人生 > >Spring Bean 生命週期之“我從哪裡來?” 懂得這個很重要

Spring Bean 生命週期之“我從哪裡來?” 懂得這個很重要

Spring bean 的生命週期很容易理解。例項化 bean 時,可能需要執行一些初始化以使其進入可用 (Ready for Use)狀態。類似地,當不再需要 bean 並將其從容器中移除時,可能需要進行一些清理,這就是它的生命週期

上一篇文章 面試還不知道BeanFactory和ApplicationContext的區別? 中說明了介面 Beanfactory 和 Applicationcontext 可以通過 T getBean(String name, Class<T> requiredType) 方法從 Spring 容器中獲取bean,區別是,前者是懶載入形式,後者是預載入的形式。那麼問題來了:

這些 Spring Beans 是怎麼生成出來的呢?

在正式回答這個問題之前,先解答一些有關 Java Bean, Spring Bean 和 Spring IoC 容器這些概念性的疑惑,我希望通過下面這個例子形象說明這些問題:

小學生 (Java Bean)通過提交資料申請(元資料配置)加入了少先隊(Spring Ioc 容器),學習了一些精神與規定之後,變成了少先隊員(Spring Bean)

從這裡可以看出,Java Bean 和 Spring Bean 都是具有特定功能的物件,小學生還是那個小學生,只不過加入了少先隊之後有了新的身份,新的身份要按照組織 (Spring Ioc)的規定履行特定義務

來看下圖加深一下了解

首先要有容器,例項化 Spring Ioc 容器是非常簡單的,介面 org.springframework.context.ApplicationContext 表示Spring IoC容器,負責例項化,配置和組裝上述 bean。 容器通過讀取配置元資料獲取有關要例項化,配置和組裝的物件的指令。 配置元資料通常以XML,Java 註解或程式碼的形式表示。 它允許你自己表達組成應用程式的物件以及這些物件之間豐富的相互依賴性,比如這樣:

ApplicationContext context = new ClassPathXmlApplicationContext(new String[] {"spring.xml", "spring1.xml"});

有了容器,我們需要做哪些處理,使其內部物件變為 Ready for Use 的狀態?
我們需要通過 Spring 容器例項化它們,Spring 為我們提供了三種方式:

三種初始化方式

InitializingBean

Spring 為我們提供了 InitializingBean 介面

public interface InitializingBean {
    void afterPropertiesSet() throws Exception;
}

我們可以通過實現 InitializingBean 介面,在其唯一方法 afterPropertiesSet 內完成例項化的工作,但是 Spring Framework 官方並不建議我們通過這種方法來完成 Bean 的例項化,這是一種強耦合的方式,我們看到框架層面才會用到這個方法。

@PostConstruct

這種方式是 Spring 非常提倡的一種方式,我們通常將其標記在方法上即可,通常習慣將這個方法起名為 init()

@PostConstruct
public void init() {
  System.out.println("Inside init() method...");
}

init-method

你應該見過這種初始化方式:

public class MyClass {
   public void init() {
      // perform post-creation logic here
   }
}

@Configuration
public class AppConfig {
   @Bean(initMethod = "init")
   public MyClass myclass() {
      return new MyClass ();
   }
}

你也應該見過這種配置方式:

<bean id="myClass" class="com.demo.MyClass" init-method="init"/>

沒錯,這只是同樣功能的不同實現方式罷了
以上就是三種初始化 Spring Beans 的方式,我們在框架中看到過三種方式在組合使用,那麼組合使用的呼叫順序是什麼呢?

  1. 首先@PostConstruct 會被最先呼叫
  2. 其次 InitializingBean.afterPropertiesSet() 方法將會被呼叫
  3. 最後呼叫通過 XML 配置的 init-method 方法或通過設定 @Bean 註解 設定 initMethod 屬性的方法

瞭解了這些,你也就瞭解了 Spring Bean 是怎麼來的了

通過圖示來說明一下:

組合shying,這個呼叫順序很難記憶嗎嗎?

PostConstruct (P),afterPropertiesSet (A),init-method (I) ---> PAI (圓周率π)

BeanPostProcessor

BeanPostProcessor 介面,大家也應該有印象,裡面只有兩個方法:

public interface BeanPostProcessor {
    Object postProcessBeforeInitialization(Object var1, String var2) throws BeansException;

    Object postProcessAfterInitialization(Object var1, String var2) throws BeansException;
}

看方法名,BeforeInitialization 和 AfterInitialization,我們應該猜得出,這是在上述三種方式的前和後,算是一種全域性的切面思想,我們經常會使用 postProcessAfterInitialization 方法,通過讀取 Bean 的註解完成一些後續邏輯編寫與屬性的設定,現在 Ready for Use之前是這樣:

Ready for Use 之前,瞭解這些內容,已可以基本滿足日常的工作內容,但這並不是 Ready for Use 的全部內容,Spring Bean 整個生命週期的流程應該是這樣的,後續文章會逐步點亮:

靈魂追問

  1. 瞭解了 Spring Bean 是怎麼來的?那它是怎麼沒的呢?什麼時候需要銷燬他們呢?
  2. Spring 框架中 XxxxAware,這些類有什麼作用,能在 Ready for Use 之前有用處嗎?
  3. 你日常的工作中有充分利用今天說明的這些內容嗎?懂得這些會大大方便你的程式設計

補充說明

  1. 雖然當下流行以註解宣告方式進行程式設計,甚至高版本 Spring 會將一些方法標記為過時,但文章說明依舊會使用 XMLBeanFactory 這類方法,包括 XML 配置。這樣做,只不過為了更清晰的說明問題。
  2. 另外將 Spring Bean 宣告週期的講解,進行拆分,是為了讓大家有獨立的思考空間,帶著問題去思考、時間,而不是被動的填充,最終串聯起自己的學習網路,這樣理解的更深刻,具體請看之前寫的文章 程式猿為什麼要看原始碼, 後續內容請持續關注

歡迎持續關注公眾號:「日拱一兵」,後續會出一系列文章點亮 Spring Bean 週期圖,以完整程式碼施力說明這個週期的順序;同時進行 Spring 知識點解釋與串聯,輕鬆搞定面試那點事,以及在工作中充分利用 Spring 的特性

推薦閱讀

  • 面試還不知道 BeanFactory 和 ApplicationContext 的區別?
  • 如何有效預防 XSS?這幾招管用!!
  • 犯罪心理解讀 Mybatis 攔截器
  • 不得不知的責任鏈設計模式
  • 如何設計好的 RESTful API?

相關推薦

Spring Bean 生命週期哪裡?” 懂得這個重要

Spring bean 的生命週期很容易理解。例項化 bean 時,可能需要執行一些初始化以使其進入可用 (Ready for Use)狀態。類似地,當不再需要 bean 並將其從容器中移除時,可能需要進行一些清理,這就是它的生命週期 上一篇文章 面試還不知道BeanFactory和Applicati

spring-bean生命週期初始化和銷燬的三種方式

1,註解bean之指定init-method/destroy-method 這種方式spring註解之@Bean註解,這邊再簡單演示如下: 配置類中增加一個bean如下: /** * 定義一個bean物件 * @return */

Spring Bean 生命週期destroy——終極信仰

上一篇文章 Spring Bean 生命週期之我從哪裡來 說明了我是誰? 和 我從哪裡來? 的兩大哲學問題,今天我們要討論一下終極哲學我要到哪裡去? 初始化 Spring Bean 有三種方式: @PostConstruct InitializingBean.afterPropertiesSet() i

Spring Bean生命週期的理解(三)------BeanFactory和FactoryBean

前言 大家可能使用Spring框架已經很久了,但是對其中的一些概念可能會比較模糊,比如BeanFactory和FactoryBean,詐一看,兩個沒啥區別,仔細研究後發現,其實本質上是兩個不同的單元。 概念 BeanFactory 字面意思講就是

Spring Bean生命週期的理解(五)------InitializingBean

前言 Spring Bean建立後,提供了針對於Bean的兩種初始化方式: 實現InitializingBean介面; 設定init-method屬性; 本文介紹的是實現InitializingBean介面的方式; 實現 1.定義MyIniti

原始碼看Spring bean 生命週期

在Spring中,bean一般都以單例模式存在,除非我們將singleton屬性設為false。 單例在多執行緒的環境下需要考慮執行緒安全的問題,對於一些公共的資源或資料應該怎麼處理才能保證安全,應該在什麼時機訪問這些資源最恰當。 熟悉了spring bean的整個生命週

5.Spring Bean生命週期.md

文章目錄 5.Spring Bean生命週期 生命週期流程圖 說明 總結 5.Spring Bean生命週期 生命週期流程圖 說明 *呼叫InstantitationAwareBeanP

Spring Bean生命週期回撥——初始化回撥(init-method)與銷燬回撥(destroy-method)

實現Bean初始化回撥和銷燬回撥各有三種方法,一是實現介面方法,二是在XML配置,三是使用註解 初始化回撥(init-method) 1、使用介面 org.springframework.beans.factory.InitializingBean介面類的作用是:在容器設定bean必

Spring Bean生命週期詳解

  在Spring中 Bean 可謂是一個核心的元素,當我們結合Spring進行程式設計的時候也離不開Bean,面對這樣重要的一個角色,瞭解其生命週期和該生命週期所涉及的環節對我們更加熟練靈活地使用Bean是很有Bean必要的,下面我們就來詳細分析下Bean的生

Spring Bean生命週期

spring bean的生命週期 spring bean生命週期1、Spring對bean進行例項化; 2、Spring將值和bean的引用注入到bean對應的屬性中; 3、如果bean實現了BeanNameAware介面,Spring將bean的ID傳遞給setBea

一步步剖析spring bean生命週期

 關於spring bean的生命週期,是深入學習spring的基礎,也是難點,本篇文章將採用程式碼+圖文結論的方式來闡述spring bean的生命週期, 本篇文章將闡述清楚下圖。    一  專案結構及原始碼 1.程式目錄結構  2.ap

SpringBean生命週期[email protected]方法進行物件的初始化

方法:通過@Bean指定init-method和destroy-method; 注:單例項和原型模式物件的建立時間和初始化銷燬的時間順序不同。 一、單例項模式 1、建立Car例項物件,並建立初始化和銷燬方法 package com.atguigu.bean; imp

2.SpringBean生命週期和組裝方式

1.Spring IoC容器概述    Spring IoC容器:      Spring容器即體現了IoC原理    Spring容器通過讀取配置元資料負責對Beans例項化、配置和裝配     配置元資

Spring註解】2、Bean生命週期

1、初始化和銷燬 通過@Bean註解的initMethod和destroyMethod屬性 InitializingBean介面、DisposableBean介面 可以使用JSR250: @PostConstruct:在Bean建立完成並且屬性

Spring 5 設計模式 - bean生命週期和使用的模式

Spring 5 設計模式 - bean生命週期和使用的模式 生命週期和階段 初始化階段 載入bean定義 初始化bean例項 使用BeanPostProcessor自定義bean 初始化擴充套件點

Spring原始碼系列 — Bean生命週期

前言 上篇文章中介紹了Spring容器的擴充套件點,這個是在Bean的建立過程之前執行的邏輯。承接擴充套件點之後,就是Spring容器的另一個核心:Bean的生命週期過程。這個生命週期過程大致經歷了一下的幾個階段 在本節中重點介紹例項化、填充裝配、喚醒Aware方法、BeanPostProce

springbean生命週期

我們都知道servlet的生命週期是:例項化、初始化、接受處理請求、銷燬。 spring上下文中bean也是類似的: 我們的bean都是交給spring管理的,也就是我們將bean的建立、管理控制權都交給了spring容器也稱為IOC容器 當然IOC容器初始化時

總結Spring框架擴充套件點(二)bean生命週期中的擴充套件點(持續更新中...)

面向業務開發的時候,程式設計師需要明白業務的邏輯,並設計程式碼結構。而在進行中介軟體開發的時候,則需要明白框架的邏輯,進行開發。 所以要開發提供給spring的中介軟體,需要知道spring中有哪些擴充套件點,好在對應的地方插入我們的功能。 1. Spring容器初始化b

Bean管理生命週期BeanPostProcessor

package com.imooc.ioc.demo3; public interface UserDao { public void findAll(); public void

Spring的IOC、Spring物件初始化bean時機、Spring容器生命週期

IOC指的是控制反轉,把物件的建立、初始化、銷燬等工作都交給Spring容器。由spring容器來控制物件的生命週期。 Spring物件初始化bean時機: 在預設情況下,只要在Spring容器中配置了一個bean,容器在啟動時就會例項化該bean,單例模式。 如果在Spr