Вступление:
По умолчанию среда Spring загружает и охотно инициализирует все компоненты при запуске самого приложения. В нашем приложении у нас могут быть довольно ресурсоемкие компоненты. Мы предпочтем загружать такие бобы по мере необходимости. Мы можем добиться этого, используя аннотацию Spring @Lazy .
В этом уроке мы узнаем, как использовать аннотацию @Lazy для ленивой загрузки наших bean-компонентов.
Ленивая инициализация:
Если мы пометим наш класс конфигурации Spring аннотацией @Lazy , то все определенные bean-компоненты с аннотацией @Bean будут загружены лениво:
|
01
02
03
04
05
06
07
08
09
10
11
12
13
14
15
|
@Configuration@ComponentScan(basePackages = "com.programmergirl.university")@Lazypublic class AppConfig { @Bean public Student student() { return new Student(); } @Bean public Teacher teacher() { return new Teacher(); }} |
Мы также можем лениво загрузить только один компонент, используя эту аннотацию на уровне метода:
|
1
2
3
4
5
|
@Bean@Lazypublic Teacher teacher() { return new Teacher();} |
Тестирование Lazy Загрузка:
Давайте быстро протестируем эту функциональность, запустив наше приложение:
|
01
02
03
04
05
06
07
08
09
10
11
12
13
|
public class SampleApp { private static final Logger LOG = Logger.getLogger(SampleApp.class); public static void main(String args[]) { AnnotationConfigApplicationContext context = new AnnotationConfigApplicationContext(AppConfig.class); LOG.info("Application Context is already up"); // Beans in our Config class lazily loaded Teacher teacherLazilyLoaded = context.getBean(Teacher.class); Student studentLazilyLoaded = context.getBean(Student.class); }} |
На нашей консоли мы увидим:
|
1
2
3
4
5
6
|
Bean factory for ...AnnotationConfigApplicationContext: ...DefaultListableBeanFactory: [...]...Application Context is already upInside Teacher ConstructorInside Student Constructor |
Очевидно, что Spring инициализировал bean-компоненты Student и Teacher по требованию, а не при настройке контекста приложения.
С аннотацией @Autowired :
Мы также можем использовать аннотацию @Lazy в точке внедрения: конструкторе, установщике или на уровне поля.
Допустим, у нас есть класс Classroom, который мы хотим лениво загрузить:
|
1
2
3
4
5
6
7
8
|
@Component@Lazypublic class Classroom { public Classroom() { System.out.println("Inside Classroom Constructor"); } ...} |
И он связан с компонентом University с помощью аннотации @Autowired :
|
01
02
03
04
05
06
07
08
09
10
11
12
13
14
15
16
|
@Componentpublic class University { @Lazy @Autowired private Classroom classroom; public University() { System.out.println("Inside University Constructor"); } public void useClassroomBean() { this.classroom.getDetails(); ... }} |
Здесь мы лениво вводили бин класса . И поэтому, создавая экземпляр объекта University , Spring создаст и отобразит для него прокси-объект Classroom . Наконец, когда мы вызываем useClassroomBean () , только тогда он создаст фактический экземпляр Classroom :
|
1
2
3
4
5
6
7
8
9
|
// in our main() methodAnnotationConfigApplicationContext context = new AnnotationConfigApplicationContext(); LOG.info("Application Context is already up"); University university = context.getBean(University.class);LOG.info("Time to use the actual classroom bean...");university.useClassroomBean(); |
Приведенный выше код создаст следующие журналы:
|
1
2
3
4
5
6
7
|
Bean factory for ...AnnotationConfigApplicationContext: ...DefaultListableBeanFactory: [...] ...Inside University Constructor... Application Context is already upTime to use the actual classroom bean...Inside Classroom Constructor |
Как мы видим, создание экземпляра объекта Classroom откладывается до тех пор, пока он действительно не понадобится.
Обратите внимание, что для отложенной инъекции мы должны использовать аннотацию @Lazy как для класса компонента, так и для точки внедрения.
Вывод:
В этом быстром уроке мы узнали, как лениво загружать бины Spring. Мы говорили о ленивой инициализации и ленивой инъекции.
|
Опубликовано на Java Code Geeks с разрешения Шубхры Шриваставы, партнера нашей программы JCG . Смотрите оригинальную статью здесь: Spring @Lazy Аннотация Мнения, высказанные участниками Java Code Geeks, являются их собственными. |