Мързелива инициализация в Spring Boot 2

1. Общ преглед

В този урок ще видим как да конфигурираме мързелива инициализация на ниво приложение, започвайки с Spring Boot 2.2

2. Мързелива инициализация

По подразбиране през пролетта всички дефинирани компоненти и техните зависимости се създават, когато се създаде контекстът на приложението.

За разлика от това, когато конфигурираме боб с мързелива инициализация, бобът ще бъде създаден и неговите зависимости ще бъдат инжектирани, след като са необходими.

3. Зависимостта на Maven

За да получим Spring Boot 2.2 в нашето приложение, трябва да го включим в нашия път на класа.

С Maven можем просто да добавим зависимостта spring-boot-starter :

  org.springframework.boot spring-boot-starter 2.2.2.RELEASE   

4. Активирайте Lazy Initialization

Spring Boot 2.2 въвежда свойството spring.main.lazy-initialization , което улеснява конфигурирането на мързелива инициализация в цялото приложение.

Задаването на стойност на свойството на true означава, че всички компоненти в приложението ще използват мързелива инициализация.

Нека конфигурираме свойството в нашия конфигурационен файл application.yml :

spring: main: lazy-initialization: true

Или, ако случаят е такъв, в нашия файл application.properties :

spring.main.lazy-initialization=true

Тази конфигурация засяга всички зърна в контекста. Така че, ако искаме да конфигурираме мързелива инициализация за конкретен боб, можем да го направим чрез подхода @Lazy .

Още повече, можем да използваме новото свойство, в комбинация с анотацията @Lazy , зададена на false .

Или с други думи, всички дефинирани зърна ще използват мързелива инициализация, с изключение на тези, които изрично конфигурираме с @Lazy (false) .

5. Бягай

Нека създадем проста услуга, която ще ни позволи да тестваме това, което току-що описахме.

Чрез добавяне на съобщение към конструктора, ние ще знаем точно кога бобът се създава.

public class Writer { private final String writerId; public Writer(String writerId) { this.writerId = writerId; System.out.println(writerId + " initialized!!!"); } public void write(String message) { System.out.println(writerId + ": " + message); } }

Също така, нека създадем SpringApplication и инжектираме услугата, която сме създали преди.

@SpringBootApplication public class Application { @Bean("writer1") public Writer getWriter1() { return new Writer("Writer 1"); } @Bean("writer2") public Writer getWriter2() { return new Writer("Writer 2"); } public static void main(String[] args) { ApplicationContext ctx = SpringApplication.run(Application.class, args); System.out.println("Application context initialized!!!"); Writer writer1 = ctx.getBean("writer1", Writer.class); writer1.write("First message"); Writer writer2 = ctx.getBean("writer2", Writer.class); writer2.write("Second message"); } }

Нека зададем стойност на свойството spring.main.lazy-initialization на false и стартираме нашето приложение.

Writer 1 initialized!!! Writer 2 initialized!!! Application context initialized!!! Writer 1: First message Writer 2: Second message

Както виждаме, компонентите бяха създадени, когато контекстът на приложението се стартира.

Сега нека променим стойността на spring.main.lazy-initialization на true и стартираме нашето приложение отново.

Application context initialized!!! Writer 1 initialized!!! Writer 1: First message Writer 2 initialized!!! Writer 2: Second message

В резултат на това приложението не е създало зърната по време на стартиране, а само когато е имало нужда от тях.

6. Ефекти от мързелива инициализация

Разрешаването на мързелива инициализация в цялото приложение може да доведе до положителни и отрицателни ефекти.

Нека да поговорим за някои от тях, както са описани в официалното съобщение за новата функционалност:

  1. Мързеливата инициализация може да намали броя на зърната, създадени при стартиране на приложението - следователно можем да подобрим времето за стартиране на приложението
  2. Тъй като нито един от компонентите не се създава, докато не е необходим, бихме могли да маскираме проблеми, като ги вземем в изпълнение, вместо време за стартиране
  3. Проблемите могат да включват грешки при липса на памет, неправилни конфигурации или грешки, открити от дефиниция на клас
  4. Също така, когато сме в уеб контекст, задействането на създаване на боб при поискване ще увеличи латентността на HTTP заявките - създаването на боб ще засегне само първата заявка, но това може да има отрицателно въздействие при балансиране на натоварването и автоматично мащабиране .

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

В този урок конфигурирахме мързелива инициализация с новото свойство spring.main.lazy-initialization, въведено в Spring Boot 2.2.

Както винаги, изходният код за този урок е достъпен в GitHub.