Справочное руководство по Spring 5: управление жизненным циклом компонентов

Spring Boot Java Spring

Эта статья участвовала в третьем этапе курса «Высокоэффективное обновление» тренировочного лагеря для создателей наггетсов. Подробнее см.:Dig Li Project | Идет третий этап тренировочного лагеря создателя, «написание» личного влияния.

Обратные вызовы жизненного цикла Spring Bean

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

В Spring нам обычно нужно выполнять некоторую дополнительную обработку ресурсов, когда компонент только инициализируется или когда компонент уничтожается. Spring предоставляет интерфейсы InitializingBean и DisposableBean, первый вызывает afterPropertiesSet(), а второй вызывает destroy(), чтобы бины могли выполнять определенные действия при инициализации и уничтожении бинов.

Следующим образом:

public class SampleInitializingBean implements InitializingBean {

    @Override
    public void afterPropertiesSet() throws Exception {
    log.info("inside afterPropertiesSet");
    }
}
public class SampleDisposableBean implements DisposableBean {


    @Override
    public void destroy() throws Exception {
        log.info("destroy");
    }
}

Конечно, это связано с кодом Spring. Мы можем использовать аннотации JSR-250 @PostConstruct и @PreDestroy для отделения от среды Spring.

Третий метод заключается в использовании сконфигурированных методов init-method и destroy-method или в использовании атрибутов initMethod @Bean и атрибута destroyMethod @Bean.

Следующим образом:

    <bean id="exampleInitBean" class="com.flydean.beans.ExampleBean" 
          init-method="init" destroy-method="destroy"/>

Ниже приведен пример аннотации @Bean:

    @Bean(initMethod = "init",destroyMethod = "destroy")
    public ExampleBean getExampleBean(){
        return new ExampleBean();
    }

Вы также можете добавить метод инициализации по умолчанию и метод уничтожения для всех bean-компонентов:

<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.xsd"
    default-init-method="init" default-destroy-method="destroy">

Суммируйте механизмы жизненного цикла

Начиная с Spring 2.5, у вас есть 3 способа управления жизненным циклом компонента:

  • Интерфейс обратного вызова InitializingBean и DisposableBean
  • Пользовательские методы init() и destroy().
  • Аннотации @PostConstruct и @PreDestroy.

Если для инициализации настроено несколько имен для нескольких жизненных циклов, порядок выполнения следующий:

  • Аннотации методов для @PostConstruct
  • Метод afterPropertiesSet() в интерфейсе InitializingBean
  • собственный метод init()

Тот же Destroy в том же порядке:

  • Аннотации методов для @PreDestroy
  • Метод destroy() в интерфейсе DisposableBean
  • Пользовательский метод destroy()

обратные вызовы запуска и завершения работы

Выше мы говорили о обратных вызовах, когда бины инициализируются и уничтожаются. Как правило, этого достаточно. Если вам нужно самостоятельно управлять объектами жизненного цикла, например запускать и останавливать некоторые фоновые процессы, Spring предоставляет интерфейс Lifecycle.

public interface Lifecycle {

    void start();

    void stop();

    boolean isRunning();
}

Любой объект, управляемый Spring, может реализовать интерфейс Lifecycle. Когда ApplicationContext получает сигнал запуска или остановки, он передает сигнал всем реализациям интерфейса Lifecycle.

Spring предоставляет интерфейс LifecycleProcessor, реализация которого по умолчанию — DefaultLifecycleProcessor:

public interface LifecycleProcessor extends Lifecycle {

	/**
	 * Notification of context refresh, e.g. for auto-starting components.
	 */
	void onRefresh();

	/**
	 * Notification of context close phase, e.g. for auto-stopping components.
	 */
	void onClose();

}

onRefresh() и onClose() будут вызывать методы start() и close(), реализующие интерфейс Lifecycle.

Если вам нужно реализовать порядок обратных вызовов запуска и выключения, вы можете реализовать интерфейс SmartLifecycle, который предоставляет метод getPhase():

 public interface SmartLifecycle extends Lifecycle, Phased {

    boolean isAutoStartup();

    void stop(Runnable callback);
}

При запуске первым запускается объект с наименьшей фазой. При остановке выполнить в обратном порядке.

Изящно закрыть контейнер Spring IoC

Если это веб-приложение Spring, веб-реализация ApplicationContext Spring уже имеет код для корректного закрытия контейнера Spring IoC.

Здесь мы рассматриваем не веб-ситуацию, нам нужно зарегистрировать хук выключения на JVM. Это обеспечит корректное завершение работы и вызовет соответствующий метод уничтожения в одноэлементном компоненте для освобождения всех ресурсов.

Вызовите registerShutdownHook() в интерфейсе ConfigurableApplicationContext, чтобы зарегистрировать перехватчик выключения, следующим образом:

    public static void main(final String[] args) throws Exception {
        ConfigurableApplicationContext ctx = new ClassPathXmlApplicationContext("bean-lifecycle.xml");

        // add a shutdown hook for the above context...
        ctx.registerShutdownHook();

        // app runs here...

        // main method exits, hook is called prior to the app shutting down...
    }

Код в этом разделе может относиться кbean-lifecycle

Дополнительные руководства см.блог флайдина