1. Overview
1.概述
By default, Spring creates all singleton beans eagerly at the startup/bootstrapping of the application context. The reason behind this is simple: to avoid and detect all possible errors immediately rather than at runtime.
默认情况下,Spring会在应用上下文的启动/启动时急切地创建所有单体Bean。这背后的原因很简单:为了避免并立即检测所有可能的错误,而不是在运行时。
However, there’re cases when we need to create a bean, not at the application context startup, but when we request it.
然而,在有些情况下,我们需要创建一个Bean,不是在应用上下文启动时,而是在我们请求时。
In this quick tutorial, we’re going to discuss Spring’s @Lazy annotation.
在这个快速教程中,我们将讨论Spring的@Lazy注解。。
2. Lazy Initialization
2.懒惰的初始化
The @Lazy annotation has been present since Spring version 3.0. There’re several ways to tell the IoC container to initialize a bean lazily.
@Lazy注解从Spring 3.0版本开始出现。有几种方法可以告诉IoC容器懒惰地初始化一个Bean。
2.1. @Configuration Class
2.1.@Configuration类
When we put @Lazy annotation over the @Configuration class, it indicates that all the methods with @Bean annotation should be loaded lazily.
当我们把@Lazy注解放在@Configuration类上时,它表示所有带有@Bean注解的方法应该被懒惰地加载。
This is the equivalent for the XML based configuration’s default-lazy-init=“true“ attribute.
这相当于基于XML的配置的default-lazy-it=“true“属性。
Let’s have a look here:
让我们来看看这里。
@Lazy
@Configuration
@ComponentScan(basePackages = "com.baeldung.lazy")
public class AppConfig {
@Bean
public Region getRegion(){
return new Region();
}
@Bean
public Country getCountry(){
return new Country();
}
}
Let’s now test the functionality:
现在我们来测试一下这个功能。
@Test
public void givenLazyAnnotation_whenConfigClass_thenLazyAll() {
AnnotationConfigApplicationContext ctx
= new AnnotationConfigApplicationContext();
ctx.register(AppConfig.class);
ctx.refresh();
ctx.getBean(Region.class);
ctx.getBean(Country.class);
}
As we see, all beans are created only when we request them for the first time:
正如我们所看到的,所有的Bean只有在我们第一次请求时才会被创建。
Bean factory for ...AnnotationConfigApplicationContext:
...DefaultListableBeanFactory: [...];
// application context started
Region bean initialized
Country bean initialized
To apply this to only a specific bean, let’s remove the @Lazy from a class.
为了只将其应用于特定的Bean,让我们将@Lazy从一个类中移除。
Then we add it to the config of the desired bean:
然后我们把它添加到所需的bean的配置中。
@Bean
@Lazy(true)
public Region getRegion(){
return new Region();
}
2.2. With @Autowired
2.2.有了@Autowired
Before going ahead, check out these guides for @Autowired and @Component annotations.
在继续之前,请查看这些@Autowired和@Component注释的指南。
Here, in order to initialize a lazy bean, we reference it from another one.
这里,为了初始化一个懒惰的Bean,我们从另一个Bean中引用它。
The bean that we want to load lazily:
我们想懒散地加载的bean。
@Lazy
@Component
public class City {
public City() {
System.out.println("City bean initialized");
}
}
And it’s reference:
而且它是参考。
public class Region {
@Lazy
@Autowired
private City city;
public Region() {
System.out.println("Region bean initialized");
}
public City getCityInstance() {
return city;
}
}
Note, that the @Lazy is mandatory in both places.
注意,@Lazy在这两处都是必须的。。
With the @Component annotation on the City class and while referencing it with @Autowired:
用@Component注解在City类上,同时用@Autowired:来引用它。
@Test
public void givenLazyAnnotation_whenAutowire_thenLazyBean() {
// load up ctx appication context
Region region = ctx.getBean(Region.class);
region.getCityInstance();
}
Here, the City bean is initialized only when we call the getCityInstance() method.
在这里,城市Bean只在我们调用getCityInstance()方法时被初始化。
3. Conclusion
3.结论
In this quick tutorial, we learned the basics of Spring’s @Lazy annotation. We examined several ways to configure and use it.
在这个快速教程中,我们学习了Spring的@Lazy注解的基础知识。我们研究了配置和使用它的几种方法。
As usual, the complete code for this guide is available over on GitHub.
像往常一样,本指南的完整代码可在GitHub上找到。