1. 程式人生 > >spring類的單例多例與啟動時懶載入與非懶載入

spring類的單例多例與啟動時懶載入與非懶載入

(1)spring 預設是單例,

單例情況下:所有執行緒對於同一個類共同擁有一個物件,此時如果在類裡面建立一個類變數如下

由於所有執行緒共享一個類物件,所以也共享一個類變數,每次請求都會增加

(2)spring 預設不是懶載入

    當spring不是懶載入時,專案啟動,spring 初始化,spring 會把所有的 掃描包下的 ,所有帶spring 註解(@Component、@Repository、@Service、@Controller)的類  都初始化,初始化時,會呼叫預設構造方法,即 空的構造方法,當定義了public AA(){   程式碼塊  }   空構造方法時,就會自動執行空構造方法中的語句,當在類中加入非空構造方法,spring會報錯誤,找不到合適的構造方法。

   當spring 設定了default-lazy-init="true",即懶載入時,spring並不會主動初始化帶註解的類,由於在controller中會注入 service層的類,由於,controller層的spring-mvc 不是懶載入,所以,當在controller中注入service時,就會初始化此service類。即呼叫到誰初始化誰。

ApplicationContext實現的預設行為就是在啟動時將所有singleton bean提前進行例項化。提前例項化意味著作為初始化過程的一部分,ApplicationContext例項會建立並配置所有的singleton bean。通常情況下這是件好事

,因為這樣在配置中的任何錯誤就會即刻被發現(否則的話可能要花幾個小時甚至幾天)。

有時候這種預設處理可能並不是你想要的。如果你不想讓一個singleton bean在ApplicationContext實現在初始化時被提前例項化,那麼可以將bean設定為延遲例項化。一個延遲初始化bean將告訴IoC 容器是在啟動時還是在第一次被用到時例項化。

在XML配置檔案中,延遲初始化將通過<bean/>元素中的lazy-init屬性來進行控制。例如:

  1. <bean id="lazy" class="com.foo.ExpensiveToCreateBean" lazy-init="true"> <!-- various properties here... --> </bean> <bean name="not.lazy" class="com.foo.AnotherBean"> <!-- various properties here... --> </bean>  

當ApplicationContext實現載入上述配置時,設定為lazy的bean將不會在ApplicationContext啟動時提前被例項化,而not.lazy卻會被提前例項化。

需要說明的是,如果一個bean被設定為延遲初始化,而另一個非延遲初始化的singleton bean依賴於它,那麼當ApplicationContext提前例項化singleton bean時,它必須也確保所有上述singleton 依賴bean也被預先初始化,當然也包括設定為延遲例項化的bean。因此,如果Ioc容器在啟動的時候建立了那些設定為延遲例項化的bean的例項,你也不要覺得奇怪,因為那些延遲初始化的bean可能在配置的某個地方被注入到了一個非延遲初始化singleton bean裡面。

注意:

懶載入與非懶載入的優缺點:
懶載入:物件使用的時候才去建立。節省資源,但是不利於提前發現錯誤

非懶載入:容器啟動時立馬建立。消耗資源,有利於提前發現錯誤

多例是以懶載入的方式產生物件

單例是以非懶載入的方式產生物件