@PreDestroy
@PreDestroy() marks a method the container calls when a bean is destroyed.
Why
Use it to release what the bean holds: flush a buffer, close a file, cancel a timer, end a subscription.
When it runs:
- for a singleton, when the context closes (
close()orcloseAsync()). Each bean is destroyed after the beans that depend on it; - for a bean of a custom scope, when its scope ends;
- for a prototype, never. The container does not track prototypes, as in Spring.
The method takes no arguments. It may return a Future. closeAsync() waits for it; close() logs it and goes on without waiting.
Errors thrown during destruction are logged and collected. They do not stop the shutdown of the other beans.
The order of destruction for one bean:
DestructionAwareBeanPostProcessor.postProcessBeforeDestruction;@PreDestroymethods;DisposableBean.destroy;- the
destroyMethodof@Bean(by default an inferredclose,shutdownordispose).
Example
import 'dart:async';
import 'dart:io';
import 'package:spring_core_dart/spring_core_dart.dart';
// Buffers log lines and writes them in batches.
@Component()
class EventBuffer {
final _lines = <String>[];
Timer? _timer;
@PostConstruct()
void start() =>
_timer = Timer.periodic(const Duration(seconds: 10), (_) => _write());
void add(String line) => _lines.add(line);
void _write() {
File('events.log').writeAsStringSync(
_lines.map((l) => '$l\n').join(),
mode: FileMode.append,
);
_lines.clear();
}
// Runs on context.close(): nothing is lost at shutdown.
@PreDestroy()
void flush() {
_timer?.cancel();
_write();
}
}
void main() {
final context = ApplicationContext.run([appBeans])
// Closes the context on Ctrl+C or SIGTERM, so @PreDestroy runs.
..registerShutdownHook();
context.getBean<EventBuffer>().add('started');
}
Parameters
None.
In Spring (Java)
The Jakarta annotation jakarta.annotation.PreDestroy:
@Component
class EventBuffer {
@PreDestroy
void flush() { ... }
}
Differences that matter: a Future-returning method is supported and awaited by closeAsync(). registerShutdownHook() reacts to SIGINT and SIGTERM and does nothing on the web.
See also
- @PostConstruct
- Lifecycle and SmartLifecycle
- @Scope
- @Bean (
destroyMethod) - ApplicationContext (
close,closeAsync,registerShutdownHook)