Эта статья участвовала в третьем этапе курса «Высокоэффективное обновление» тренировочного лагеря для создателей наггетсов. Подробнее см.: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
Дополнительные руководства см.блог флайдина