1. 概述
默認情況下,Spring 在應用程序上下文的啓動/引導過程中會立即創建所有單例 Bean。 這樣做是為了避免並儘早檢測所有可能的錯誤,而不是在運行時檢測。
然而,在某些情況下,我們需要在請求時創建 Bean,而不是在應用程序上下文啓動時創建。
在本快速教程中,我們將討論 Spring 的 @Lazy 註解。
2. 延遲初始化
<em @Lazy</em> 註解自 Spring 3.0 版本開始存在。有多種方法可以告知 IoC 容器延遲初始化一個 Bean。
2.1. <em @Configuration 類
當我們對 類應用 註解時,表示所有帶有 註解的方法應該延遲加載。
這等同於基於 XML 的配置中 “true”” 屬性。
讓我們來查看一下:
@Lazy
@Configuration
@ComponentScan(basePackages = "com.baeldung.lazy")
public class AppConfig {
@Bean
public Region getRegion(){
return new Region();
}
@Bean
public Country getCountry(){
return new Country();
}
}現在我們來測試功能:
@Test
public void givenLazyAnnotation_whenConfigClass_thenLazyAll() {
AnnotationConfigApplicationContext ctx
= new AnnotationConfigApplicationContext();
ctx.register(AppConfig.class);
ctx.refresh();
ctx.getBean(Region.class);
ctx.getBean(Country.class);
}我們看到,所有 Bean 只有在我們首次請求它們時才會被創建:
Bean factory for ...AnnotationConfigApplicationContext:
...DefaultListableBeanFactory: [...];
// application context started
Region bean initialized
Country bean initialized要將其應用於特定的 Bean,請移除該 Bean 類中的 @Lazy 註解。
然後,將其添加到所需 Bean 的配置中:
@Bean
@Lazy(true)
public Region getRegion(){
return new Region();
}2.2. 使用 @Autowired
在繼續之前,請查看有關 @Autowired 和 @Component 註解的指南。
在這裏,為了初始化惰性 Bean,我們從另一個 Bean 中引用它。
要惰性加載的 Bean:
@Lazy
@Component
public class City {
public City() {
System.out.println("City bean initialized");
}
}以下是參考資料:
public class Region {
@Lazy
@Autowired
private City city;
public Region() {
System.out.println("Region bean initialized");
}
public City getCityInstance() {
return city;
}
}請注意,@Lazy 在兩個地方都必須存在。
在對 City 類進行註解,並使用 @Autowired 引用它時,@Component 註解是必需的。
@Test
public void givenLazyAnnotation_whenAutowire_thenLazyBean() {
// load up ctx appication context
Region region = ctx.getBean(Region.class);
region.getCityInstance();
}在這裏,“City”豆僅在調用 getCityInstance() 方法時進行初始化。
3. 結論
在本快速教程中,我們學習了 Spring 的 @Lazy 註解的基礎知識。我們還探討了配置和使用它的多種方法。