Implementing Lifecycle Methods
Overview
Lifecycle methods allow you to hook into the Talon microservice lifecycle at specific points during startup, operation, and shutdown. The Talon runtime invokes these methods at well-defined stages, enabling you to:
Receive platform objects via dependency injection
Provide application objects for annotation scanning
Initialize resources and state
React to lifecycle transitions
Clean up resources during shutdown
Lifecycle methods fall into three categories:
Injection Methods
The Talon runtime invokes injection methods to provide your application with handles to platform objects. These methods are marked with @AppInjectionPoint and allow the runtime to inject objects like the AEP engine, message sender, and configuration descriptors.
Accessor Methods
The Talon runtime invokes accessor methods to gather application objects containing various annotations. These methods allow you to organize your code across multiple classes while making them discoverable to the Talon runtime.
Notification Methods
The Talon runtime invokes notification methods to notify your application of lifecycle transitions and operational events. These include initialization, finalization, and lifecycle event handlers.
See Also: Lifecycle - Complete lifecycle flow and timing
Dependency Injection
Use the @AppInjectionPoint annotation to receive platform objects from the Talon runtime.
Injectable Types
The Talon runtime can inject the following types:
SrvAppLoader
Access to application and XVM configuration descriptors
Early in Open phase
AepEngineDescriptor
Modify engine configuration before creation
After HA policy determination
AepMessageSender
Send outbound messages
After engine creation
AepEngine
Access to running engine instance
After engine creation
Injection on Fields
You can inject directly into fields:
Injection on Methods
Alternatively, inject via setter methods for more control:
Injecting the Application Loader
The application loader provides access to configuration descriptors:
Modifying the Engine Descriptor
Inject the engine descriptor to programmatically configure the engine before it's created:
See Also: AepEngineDescriptor Javadoc
Accessor Methods
Accessor methods allow you to provide objects to the Talon runtime for annotation scanning. This enables you to organize your code across multiple classes while keeping handlers, stats, and configuration discoverable.
Unified Accessor - @AppIntrospectionPoints
Use @AppIntrospectionPoints to provide objects for all types of annotation scanning:
Fine-Grained Accessors
For large applications, use fine-grained accessors to reduce the number of objects scanned for each annotation type:
@AppConfiguredAccessor
Provide objects containing @Configured annotations:
@AppEventHandlerContainersAccessor
Provide objects containing @EventHandler methods:
@AppCommandHandlerContainersAccessor
Provide objects containing @Command methods:
@AppStatContainersAccessor
Provide objects containing @AppStat annotations:
Programmatic Event Handler
For advanced use cases, provide a programmatic event handler instead of using annotations:
Note: The default event handler is only invoked for events/messages not handled by @EventHandler annotated methods (unless configured with DefaultHandlerDispatchPolicy=DispatchAlways).
See Also:
Annotations Reference - Complete annotation details
Injecting Configuration - Using @Configured
Implementing Command Handlers - Using @Command
Exposing Application Stats - Using @AppStat
Initialization and Finalization
Application Initialization - @AppInitializer
The @AppInitializer method is invoked after the engine is created and injected but before it is started:
What's Available at Initialization:
β Injected platform objects (engine, sender, etc.)
β Configuration values
β Application state factory has been provided
β Engine is not yet started
β Messaging is not yet connected
β Store is not yet open
Thread Safety:
Do not access or modify microservice state in the initializer for State Replication applications. The store is not yet open and state objects are not yet available. Use lifecycle events (like AepEngineActiveEvent) for state-dependent initialization.
Application Finalization - @AppFinalizer
The @AppFinalizer method is invoked during shutdown after the engine is stopped:
What's Available at Finalization:
β Injected platform objects still available
β Engine is stopped
β Messaging is disconnected
β Store is closed
See Also: Lifecycle - Initialize Application
State Factory for State Replication
For State Replication microservices, provide the state factory via @AppStateFactoryAccessor:
See Also: State Replication Template
Synchronous Applications
Main Method - @AppMain
For microservices that are not event-driven (sender-only applications), implement a main method:
Execution:
Invoked in a separate thread after the engine becomes primary
Runs asynchronously from message processing
Suitable for driving application logic without inbound messages
See Also: Lifecycle - Synchronous Applications
Handling Lifecycle Events
Use @EventHandler to react to lifecycle events dispatched by the Talon runtime.
Engine Lifecycle Events
AepEngineCreatedEvent
Dispatched after the engine is created but before it is started:
AepMessagingPrestartEvent
Dispatched before the engine attempts to connect to messaging:
AepEngineStartedEvent
Dispatched after the engine determines its role (primary or backup):
AepEngineActiveEvent
Dispatched when the engine becomes the active primary:
Best Practice: Use AepEngineActiveEvent to start background threads, scheduled tasks, or any processing that should only run on the primary instance.
AepMessagingStartedEvent
Dispatched after messaging startup completes:
AepEngineStoppedEvent
Dispatched when the engine stops:
Messaging Lifecycle Events
AepChannelUpEvent
Dispatched when a channel connection is established:
AepChannelDownEvent
Dispatched when a channel connection is lost:
AepBusBindingUpEvent
Dispatched when a bus binding is fully operational:
Store Lifecycle Events (State Replication)
IStoreMemberUpEvent
Dispatched when a new member joins the store cluster:
IStoreMemberInitCompleteEvent
Dispatched when store initialization completes:
IStoreBindingRoleChangedEvent
Dispatched when the store binding's role changes:
Alert Events
Alert events signal exceptional conditions:
AepMessagingFailedEvent
AepBusBindingDownEvent
See Also: Events Reference - Complete event documentation
Complete Example
Here's a complete microservice demonstrating lifecycle method implementation:
Lifecycle Execution Order
Lifecycle methods are invoked in the following order during microservice startup:
1
Load main class
XVM loads the microservice
2
@AppInjectionPoint (SrvAppLoader)
Inject application loader
3
@AppHAPolicy
Read HA policy from annotation
4
@AppInjectionPoint (AepEngineDescriptor)
Inject engine descriptor for configuration
5
@AppConfiguredAccessor
Get objects for configuration injection
6
@Configured
Inject configuration values
7
@AppCommandHandlerContainersAccessor
Get command handler containers
8
@AppStatContainersAccessor
Get stat containers
9
@AppEventHandlerContainersAccessor
Get event handler containers
10
@AppStateFactoryAccessor
Get state factory (State Replication)
11
Create engine
Engine is instantiated
12
AepEngineCreatedEvent
Engine created event dispatched
13
@AppInjectionPoint (AepEngine, AepMessageSender)
Inject engine and sender
14
@AppInitializer
Initialize application
15
Start engine
Engine determines role and starts
16
AepEngineStartedEvent
Engine started event dispatched
17
AepEngineActiveEvent
Engine active event (if primary)
18
@AppMain
Main method invoked (if present)
During shutdown:
1
Stop engine
Engine stops processing
2
AepEngineStoppedEvent
Engine stopped event dispatched
3
@AppFinalizer
Finalize application
See Also: Lifecycle - Complete Flow
Best Practices
β
Do
Use AepEngineActiveEvent for primary-only initialization
Use @AppIntrospectionPoints for simple applications
Reduces boilerplate for small to medium applications
Single method to provide all objects
Use fine-grained accessors for large applications
Improves startup performance by reducing object scanning
Better organization of handler containers
Inject AepEngineDescriptor to configure the engine
Use field injection for simplicity
Less code
Clear and concise
Clean up resources in @AppFinalizer
β Don't
Don't access microservice state in @AppInitializer (State Replication)
Don't start background tasks in @AppInitializer
Don't perform long-running operations in lifecycle methods
Keep initialization fast
Use background threads for heavy operations
Don't assume messaging is ready in @AppInitializer
Don't use @AppMain for event-driven applications
@AppMain is for sender-only applications
Event-driven apps should use @EventHandler
Thread Safety
Lifecycle methods are single-threaded: Only one lifecycle method executes at a time
Event handlers are single-threaded: Message processing is single-threaded by design
Background threads require synchronization: If you start background threads, ensure proper synchronization when accessing shared state
Volatile fields for stats: Use volatile for statistics accessed from background threads
See Also
Conceptual
Lifecycle - Complete lifecycle flow and timing
Development Model - Lifecycle method categories
Reference
Annotations - Complete annotation reference
Events - Lifecycle and runtime events
How-To Guides
Injecting Configuration - Using @Configured
Implementing Command Handlers - Using @Command
Exposing Application Stats - Using @AppStat
Initializing the Microservice - Initialization patterns
Templates
Event Sourcing Template - Event Sourcing example
State Replication Template - State Replication example
Last updated

