Хотите ускорить запуск приложения и сэкономить память? Аннотация @Lazy
в Spring поможет инициализировать бины только тогда, когда они действительно понадобятся. Команда Spring АйО поможет разбобраться, как применять @Lazy
точечно и глобально, в чём плюсы и подводные камни ленивой инициализации, и как избежать неожиданных ошибок на проде.
По умолчанию Spring инициализирует все singleton-бины во время запуска приложения. Аннотация @Lazy
позволяет изменить это поведение, инициализируя бины только по мере необходимости. Используя аннотацию @Lazy
можно существенно снизить потребление памяти и уменьшить время запуска приложения, отметив бины, которые используются в приложении не так часто и занимают немало памяти.
Способы применения
Чтобы сделать бин лениво инициализируемым, нужно отметить его аннотацией @Lazy
в месте его объявления:
@Lazy
@Component
public class MyComponent {
//...
}
@Configuration
@Lazy
public class LazyConfig {
// Все объявленные в этом конфиге бины будут ленивыми
}
@Configuration
public class AppConfig {
//Этот конкретный бин будет ленивым
@Bean
@Lazy
public MyBean myBean() {
return new MyBean();
}
}
А также в месте его инжекции:
@Service
public class MyService {
private final MyBean myBean;
private final MyComponent myComponent;
public MyService(@Lazy MyBean myBean, @Lazy MyComponent myComponent) {
this.myBean = myBean;
this.myComponent = myComponent;
}
}
Если не воспользоваться аннотацией @Lazy
в месте объявления бина или в месте его инжекции, то он НЕ БУДЕТ ленивым.
Ленивая инициализация контекста по умолчанию
Чтобы сделать инициализацию ленивой для всего контекста, можно добавить следущее свойство в конфигурационный файл:
spring.main.lazy-initialization=true
Однако стоит быть осторожным с этим подходом. Ошибки инициализации могут возникнуть не во время запуска приложения, а позже – в рантайме, что усложнит их обнаружение и исправление (что в целом справедливо и при ленивой инициализации лишь некоторых бинов). Но если вы всё таки решите использовать глобальную ленивую инициализацию, можно исключить определённые бины, инициализируя их жадно (во время запуска приложения) с помощью @Lazy(false)
:
@Service
@Lazy(false)
public class MyService {
// код
}
А много ли бинов лениво инициализируется на вашем проекте? Может быть вообще все? Поделитесь своим опытом в комментариях, будет интересно почитать!

Присоединяйтесь к русскоязычному сообществу разработчиков на Spring Boot в телеграм — Spring АйО, чтобы быть в курсе последних новостей из мира разработки на Spring Boot и всего, что с ним связано