寫在前面
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註解驅動開發不再迷茫。