https://blog.csdn.net/m0_37941483/article/details/90679524
1.概述
默认情况下,Spring会在应用程序上下文的启动时创建所有单例bean。这背后的原因很简单:立即避免和检测所有可能的错误,而不是在运行时。
但是,有些情况下我们需要创建一个bean,而不是在应用程序上下文启动时,而是在我们请求时。
在这个快速教程中,我们将讨论Spring的@Lazy注释。
2.懒加载
这个注解出现在Spring 3.0以后,有好几种方法实现来懒加载实例化bean.
2.1 @Configuration class
@Configuraiton 和@lazy 一起使用时,意味着所有使用@Bean 的方法都是懒加载
@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,让我们从类中删除@Lazy。
然后我们将它添加到所需bean的配置中:
@Bean
@Lazy(true)
public Region getRegion(){
return new Region();
}
2.2 使用@Autowired
这里,为了初始化一个懒惰的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类上的@Component注解并在使用@Autowired引用它时:
@Test
public void givenLazyAnnotation_whenAutowire_thenLazyBean() {
// load up ctx appication context
Region region = ctx.getBean(Region.class);
region.getCityInstance();
}
在这里,当我们调用getCityInstance(0 方法时,city bean 才被初始化。