Spring: Жизненный цикл бинов, методы init() и destroy()

Моя цель - предложение широкого ассортимента товаров и услуг на постоянно высоком качестве обслуживания по самым выгодным ценам.

Disclaimer

Всем привет! Я начинающий Java-разработчик. В рамках развития своей карьеры я решил сделать две вещи:

  • Завести канал в ТГ, где собираюсь рассказывать о себе, своем пути и проблемах, с которыми сталкиваюсь - https://t.me/java_wine

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

Надеюсь, буду полезен сообществу и новичкам, которые пойдут по моим или чьим-то еще стопам.

Run!


Жизненный цикл любого объекта означает следующее: как и когда он появляется, как он себя ведет во время жизни и как и когда он исчезает. Жизненный цикл бина ровно про это же: «как и когда».

Жизненным циклом управляет спринг-контейнер. В первую очередь после запуска приложения запускается именно он. После этого контейнер по необходимости и в соответствии с запросами создает экземпляры бинов и внедряет необходимые зависимости. И, наконец, бины, связанные с контейнером, уничтожаются когда контейнер завершает свою работу. Поэтому, если мы хотим выполнить какой-то код во время инстанцирования бина или сразу после завершения работы контейнера, один из самых доступных нам вариантов это вынести его в специальные init() и destroy() методы.

На картинке условно это можно изобразить следующим образом

Спринг предоставляет несколько способ настроить выполнение этих методов. Для того чтобы понять и разобраться в них, давайте посмотрим на простой пример.

Попробуем создать бин HelloWorld и вызвать у него методы init() и destroy(). Сделаем это тремя разными способами:

XML

Сначала сделаем простой класс:

public class HelloWorld {
    public void init() throws Exception
    {
        System.out.println("Я инит-метод " + this.getClass().getSimpleName());
    }

    public void destroy() throws Exception
    {
        System.out.println("Я дестрой-метод " + this.getClass().getSimpleName());
    }
}

Чтобы использовать пользовательские методы init() и destroy() нам необходимо зарегистрировать их в Spring XML конфигурационном файле при описании бина:

<?xml version="1.0" encoding="UTF-8"?>
<beans xmlns="http://www.springframework.org/schema/beans"
       xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
       xsi:schemaLocation="
http://www.springframework.org/schema/beans http://www.springframework.org/schema/beans/spring-beans-3.0.xsd">

    <bean id="helloWorld" class="HelloWorld" init-method="init" destroy-method="destroy"/>

</beans>

Также потребуется класс-runner, который и запустит наш контекст:

public class App {
    public static void main(String[] args) {
        ConfigurableApplicationContext context
        					= new ClassPathXmlApplicationContext("spring.xml");
        context.close();
        }
}

Обратите внимание, что в нём указан адрес файла конфигурации бинов.

Java-код («программный метод»)

Для того чтобы это реализовать необходимо в классе бина HelloWorldByJavaCode имплементировать два интерфейса, InitializingBean и DisposableBean, а затем переопределить методы afterPropertiesSet() и destroy().

Метод afterPropertiesSet() вызывается при запуске спринг-конейтнера и инстанцировании бина, а метод destroy() сразу после того как контейнер завершит свою работу.

Чтобы вызвать метод destroy() нам необходимо явно закрыть спринг-контекст, вызвав метод close() у объекта ConfigurableApplicationContext.

Класс HelloWorldByJavaCode:

public class HelloWorldByJavaCode implements InitializingBean,
        DisposableBean {
    @Override
    public void destroy() throws Exception {
        System.out.println("Я дестрой-метод " + this.getClass().getSimpleName());
    }

    @Override
    public void afterPropertiesSet() throws Exception {
        System.out.println("Я инит-метод " + this.getClass().getSimpleName());
    }
}

В XML регистрация бина будет выглядеть так:

<bean id="helloWorldByJavaCode" class="HelloWorldByJavaCode"/>

Класс-runner остается прежним

С помощью аннотаций

Чтобы вызывать методы init() и destroy() нам необходимо указать над методами соответствующие аннотации - @PostConstruct и @PreDestroy.

Чтобы вызвать метод destroy() нам необходимо явно закрыть спринг-контекст, вызвав метод close() у объекта ConfigurableApplicationContext. Класс-runner остается прежним

Cоздадим бин HelloWorldByAnnotations.java и аннотируем соответствующие методы:

public class HelloWorldByAnnotations {

    @PostConstruct
    public void init() throws Exception
    {
        System.out.println("Я инит-метод " + this.getClass().getSimpleName());
    }

    @PreDestroy
    public void destroy() throws Exception
    {
        System.out.println("Я дестрой-метод " + this.getClass().getSimpleName());
    }
}

В XML-файле появится дополнительная строчка, отвечающая за бин, читающий аннотации:

<?xml version="1.0" encoding="UTF-8"?>
<beans xmlns="http://www.springframework.org/schema/beans"
       xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
       xsi:schemaLocation="
http://www.springframework.org/schema/beans http://www.springframework.org/schema/beans/spring-beans-3.0.xsd">

    <bean id="helloWorldByAnnotations" class="HelloWorldByAnnotations"/>
    <bean class="org.springframework.context.annotation.CommonAnnotationBeanPostProcessor"/>

</beans>

Размещу еще одну схему жизненного цикла, более полную. Взял её уже с другого ресурса. Мне кажется для понимания и подготовки к собеседованиям полезно.

Источник: https://habr.com/ru/post/658273/


Интересные статьи

Интересные статьи

Цикл for — самый базовый инструмент потока управления большинства языков программирования. Например, простой цикл for на C выглядит так: int i; for (i=0;i<N;i++) { //do someth...
Много всякого сыпется в мой ящик, в том числе и от Битрикса (справедливости ради стоит отметить, что я когда-то регистрировался на их сайте). Но вот мне надоели эти письма и я решил отписатьс...
Автор заметки, перевод которой мы сегодня публикуем, хочет рассказать о некоторых особенностях использования циклов for в Python. Цикл for — это один из краеугольных камней программировани...
В 2019 году люди знакомятся с брендом, выбирают и, что самое главное, ПОКУПАЮТ через интернет. Сегодня практически у любого бизнеса есть свой сайт — от личных блогов, зарабатывающих на рекламе, до инт...
В интернет-магазинах, в том числе сделанных на готовых решениях 1C-Битрикс, часто неправильно реализован функционал быстрого заказа «Купить в 1 клик».