bean 初始化 初探

bean 初始化<clinit> <init> 初探

java文件編譯後會爲每個類自動生成一個<clinit>和<init>函數。

<clinit> 函數是在類第一次加載到jvm方法區的時候調用,實現對類中的一些靜態變量賦值以及執行靜態語句塊。

<init>是在對象實例初始化時候調用,對類中的一些變量賦值以及執行一些語句塊。

我們還可以通過在Spring中配置的init-method,以便在bean初始化完全之前做一些操作。配置格式如下

<bean id="beanInit" class="com.study.BeanInit" init-method="init" destroy-method="destory"></bean>

實驗示例代碼:

public class BeanInit{
    private String init;
    {
        init = "init";//<init>
    }
    static private String cinit;
    static {
        cinit = "cinit";//<clinit>
    }
    private void init(){
        init = "init-method";//init
    }
    private void destory(){
    }
}

這裏寫圖片描述
這裏寫圖片描述
這裏寫圖片描述

單步調試,觀察堆棧信息

首先被調用的是<clinit>函數。

其次被調用的是<init>函數。

最後是init。

(——這裏編譯生成的<init>是有一堆尖括號的,而我們自己定義的是init)

發現<clinit>和<init>的調用棧是一致的,都是在構造函數Constructor函數中被調用。

spring在獲取對象實例的時候,會調用類的構造函數Constructor,此時發現該類並沒有加載至內存,於是classLoader這時會加載這個類,而<clinit>就是在加載過程的初始化這一步被調用的,用來初始化這個類,這時該類已經加載在內存裏,接下來便會觸發<init>來初始化這個對象。

這裏的Constructor函數是編譯器自動生成的默認無參數的構造函數。

發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章