寫在前面
Spring在啟動時,預設會將單例項bean進行例項化,並載入到Spring容器中。也就是說,單例項bean預設在Spring容器啟動的時候建立物件,並將物件載入到Spring容器中。如果我們需要對某個bean進行延遲載入,我們該如何處理呢?此時,就需要使用到@Lazy註解了。
專案工程原始碼已經提交到GitHub:https://github.com/sunshinelyz/spring-annotation
懶載入
懶載入就是Spring容器啟動的時候,先不建立物件,在第一次使用(獲取)bean的時候,建立並使用物件,大家是不是想到了在【設計模式】專題中的單例模式呢?對單例模式不太瞭解的同學可以猛戳《淺談JAVA設計模式之——單例模式(Singleton)》,也可以檢視《設計模式彙總——你需要掌握的23種設計模式都在這兒了!》來系統學習每種設計模式。
非懶載入模式
此時,我們將PersonConfig2類的配置修改成單例項bean,如下所示。
package io.mykit.spring.plugins.register.config;
import io.mykit.spring.bean.Person;
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;
/**
* @author binghe
* @version 1.0.0
* @description 測試@Scope註解設定的作用域
*/
@Configuration
public class PersonConfig2 {
@Bean("person")
public Person person(){
System.out.println("給容器中新增Person....");
return new Person("binghe002", 18);
}
}
接下來,在SpringBeanTest類中建立testAnnotationConfig5()方法,如下所示。
@Test
public void testAnnotationConfig5(){
ApplicationContext context = new AnnotationConfigApplicationContext(PersonConfig2.class);
System.out.println("IOC容器建立完成");
}
執行SpringBeanTest類中的testAnnotationConfig5()方法,輸出的結果資訊如下所示。
給容器中新增Person....
IOC容器建立完成
可以看到,單例項bean在Spring容器啟動的時候就會被建立,並載入到Spring容器中。
懶載入模式
我們在PersonConfig2的person()方法上加上@Lazy註解將Person物件設定為懶載入,如下所示。
package io.mykit.spring.plugins.register.config;
import io.mykit.spring.bean.Person;
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;
import org.springframework.context.annotation.Lazy;
/**
* @author binghe
* @version 1.0.0
* @description 測試@Scope註解設定的作用域
*/
@Configuration
public class PersonConfig2 {
@Lazy
@Bean("person")
public Person person(){
System.out.println("給容器中新增Person....");
return new Person("binghe002", 18);
}
}
此時,我們再次執行SpringBeanTest類中的testAnnotationConfig5()方法,輸出的結果資訊如下所示。
IOC容器建立完成
可以看到,此時,只是列印出了“IOC容器建立完成”,說明此時,只建立了IOC容器,並沒有建立bean物件。
那麼,加上@Lazy註解後,bean是何時建立的呢?我們在SpringBeanTest類中的testAnnotationConfig5()方法中獲取下person物件,如下所示。
@Test
public void testAnnotationConfig5(){
ApplicationContext context = new AnnotationConfigApplicationContext(PersonConfig2.class);
System.out.println("IOC容器建立完成");
Person person = (Person) context.getBean("person");
}
此時,我們再次執行SpringBeanTest類中的testAnnotationConfig5()方法,輸出的結果資訊如下所示。
IOC容器建立完成
給容器中新增Person....
說明,我們在獲取bean的時候,建立了bean物件並載入到Spring容器中。
那麼,問題又來了,只是第一次獲取bean的時候建立bean物件嗎?多次獲取會不會建立多個bean物件呢?我們再來完善下測試用例,在在SpringBeanTest類中的testAnnotationConfig5()方法中,再次獲取person物件,並比較兩次獲取的person物件是否相等,如下所示。
IOC容器建立完成
給容器中新增Person....
true
從輸出結果中,可以看出使用@Lazy註解標註後,單例項bean物件只是在第一次從Spring容器中獲取物件時建立,以後每次獲取bean物件時,直接返回建立好的物件。
總結
懶載入,也稱延時載入。僅對單例bean生效。單例bean是在Spring容器啟動的時候載入的,新增@Lazy註解後就會延遲載入,在Spring容器啟動的時候並不會載入,而是在第一次使用此bean的時候才會載入,但當你多次獲取bean的時候不會重複載入,只是在第一次獲取的時候會載入,這不是延遲載入的特性,而是單例Bean的特性。
好了,我們們今天就聊到這兒吧!別忘了給個在看和轉發,讓更多的人看到,一起學習一起進步!!
專案工程原始碼已經提交到GitHub:https://github.com/sunshinelyz/spring-annotation
寫在最後
如果覺得文章對你有點幫助,請微信搜尋並關注「 冰河技術 」微信公眾號,跟冰河學習Spring註解驅動開發。公眾號回覆“spring註解”關鍵字,領取Spring註解驅動開發核心知識圖,讓Spring註解驅動開發不再迷茫。