Перейти к основному содержимому

Краткое руководство по аннотации Spring @Lazy

· 3 мин. чтения

1. Обзор

По умолчанию Spring с готовностью создает все одноэлементные компоненты при запуске/загрузке контекста приложения. Причина этого проста: избежать и обнаружить все возможные ошибки сразу, а не во время выполнения.

Однако бывают случаи, когда нам нужно создать bean-компонент не при запуске контекста приложения, а когда мы его запрашиваем.

В этом кратком руководстве мы обсудим аннотацию Spring @Lazy .

2. Ленивая инициализация

Аннотация @Lazy присутствует с версии Spring 3.0. Есть несколько способов указать контейнеру IoC лениво инициализировать bean-компонент.

2.1. @ Класс конфигурации

Когда мы помещаем аннотацию @Lazy поверх класса @Configuration , это указывает на то, что все методы с аннотацией @Bean должны загружаться лениво .

Это эквивалентно атрибуту default-lazy-init= «true » конфигурации на основе XML.

Давайте посмотрим здесь:

@Lazy
@Configuration
@ComponentScan(basePackages = "com.foreach.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 factory for ...AnnotationConfigApplicationContext: 
...DefaultListableBeanFactory: [...];
// application context started
Region bean initialized
Country bean initialized

Чтобы применить это только к определенному компоненту, давайте удалим @Lazy из класса.

Затем добавляем его в конфиг нужного бина:

@Bean
@Lazy(true)
public Region getRegion(){
return new Region();
}

2.2. С @Autowired

Прежде чем двигаться дальше, ознакомьтесь с этими руководствами по аннотациям @Autowired и @Component .

Здесь, чтобы инициализировать ленивый компонент, мы ссылаемся на него из другого.

Компонент, который мы хотим загрузить лениво:

@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 является обязательным в обоих местах.

С аннотацией @Component в классе City и ссылкой на него с помощью @Autowired:

@Test
public void givenLazyAnnotation_whenAutowire_thenLazyBean() {
// load up ctx appication context
Region region = ctx.getBean(Region.class);
region.getCityInstance();
}

Здесь bean -компонент City инициализируется только тогда, когда мы вызываем метод getCityInstance() .

3. Заключение

В этом кратком руководстве мы изучили основы аннотации Spring @Lazy . Мы рассмотрели несколько способов его настройки и использования.

Как обычно, полный код этого руководства доступен на GitHub .