欢迎您访问程序员文章站本站旨在为大家提供分享程序员计算机编程知识!
您现在的位置是: 首页

Spring系列——@lazy注解

程序员文章站 2022-05-21 21:07:54
...

翻译自https://www.baeldung.com/spring-lazy-annotation

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 才被初始化。