Summon provides a streamlined lifecycle management system specifically designed for backend JVM applications. This guide explains how to integrate it with popular backend frameworks.
The backend lifecycle system consists of:
LifecycleOwner class that manages lifecycle states// Get the current lifecycle owner
val lifecycleOwner = currentLifecycleOwner()
// Create a lifecycle-aware component
val component = LifecycleAwareComponent(
lifecycleOwner = lifecycleOwner,
onResume = {
// Start services, open connections
println("Component is active")
},
onPause = {
// Pause operations, reduce resource usage
println("Component is paused")
},
onDestroy = {
// Cleanup resources, close connections
println("Component is destroyed")
}
)
// Don't forget to dispose when no longer needed
component.dispose()
// Add custom startup hook
JvmLifecycleOwner.addStartupHook {
// Initialize your service
println("My service is starting up")
}
// Add custom shutdown hook
JvmLifecycleOwner.addShutdownHook {
// Clean up your service
println("My service is shutting down")
}
The JVM implementation automatically detects and integrates with popular backend frameworks:
// Example of Spring Boot integration
@Component
class MySpringComponent {
@PostConstruct
fun init() {
// Get lifecycle owner
val lifecycleOwner = currentLifecycleOwner()
// Register with lifecycle
lifecycleCoroutineScope(lifecycleOwner).launch {
// This coroutine will be cancelled when the application shuts down
}
}
}
// Example of Ktor integration
fun Application.module() {
// Get lifecycle owner
val lifecycleOwner = currentLifecycleOwner()
// Register shutdown hook for cleanup
environment.monitor.subscribe(ApplicationStopping) {
// This will be called when Ktor is stopping
println("Ktor application shutting down")
}
// Start background work that respects lifecycle
whenActive(lifecycleOwner) {
// This block is only executed when the lifecycle is active
// and is automatically cancelled when it becomes inactive
}
}
// Example of Quarkus integration
@ApplicationScoped
class MyQuarkusService {
@PostConstruct
fun init() {
// Get lifecycle owner
val lifecycleOwner = currentLifecycleOwner()
// Setup lifecycle-aware component
val component = LifecycleAwareComponent(lifecycleOwner)
}
}
// Example of Micronaut integration
@Singleton
class MyMicronautService {
@PostConstruct
fun init() {
// Get lifecycle owner
val lifecycleOwner = currentLifecycleOwner()
// Use lifecycleCoroutineScope for background work
lifecycleCoroutineScope(lifecycleOwner).launch {
// This coroutine is tied to the application lifecycle
}
}
}
You can create custom integrations for other backend frameworks:
// Add to BackendIntegrations object
fun setupCustomFrameworkIntegration() {
try {
// Check if your framework is in classpath
Class.forName("com.example.framework.MainClass")
// Add lifecycle hooks
JvmLifecycleOwner.addStartupHook {
println("Custom framework started")
}
JvmLifecycleOwner.addShutdownHook {
println("Custom framework shutting down")
}
// Add deeper integration specific to your framework
} catch (e: ClassNotFoundException) {
// Framework not in classpath, skip integration
}
}
// Call your integration setup
BackendIntegrations.setupCustomFrameworkIntegration()
For backend applications, lifecycle states have these meanings:
CREATED: The component has been created but not startedSTARTED: The component is starting but not yet fully operationalRESUMED: The component is fully operational and handling requestsPAUSED: The component is still running but in a reduced capacity (e.g., during maintenance)STOPPED: The component has stopped handling requests but hasn't released resourcesDESTROYED: The component has been destroyed and all resources releasedWhen your application starts:
JvmLifecycleOwner is initialized by the first call to currentLifecycleOwner()BackendIntegrations.setupAll() method is calledThis allows your code to respond to lifecycle events regardless of which backend framework you're using, with no manual configuration required.