Component Registry and Lifecycle Registry
Components, decorators, modules, enhancers, and factories, as covered throughout this chapter, are all registered through one of two interfaces: ComponentRegistry and LifecycleRegistry.
These two registries are the heart of any ApplicationConfigurer.
Every configurer, whether the base ApplicationConfigurer, the MessagingConfigurer, the ModellingConfigurer, or the EventSourcingConfigurer, is ultimately a facade around this pair.
The convenience methods each of those configurers add exist purely for ease of use, translating a specific registration call into an operation on one of the two registries underneath.
The ComponentRegistry is the catalog of everything your application is built from.
It holds every registered Component, together with the decorators that wrap them, the modules that group them, the factories that can construct them on demand, and the enhancers that adjust or complete the registry before it is turned into a Configuration.
Because a Component is registered as a lazy builder rather than an eager instance, the ComponentRegistry is what allows components to reference each other regardless of the order in which they were registered, resolving each one only the first time it is actually requested.
The LifecycleRegistry is concerned with an entirely different question: not what exists, but when it starts and when it stops.
It holds the start and shutdown handlers attached to components and decorators, together with the phase in which each of them runs.
Where the ComponentRegistry answers "what does my application consist of, and how is each part built", the LifecycleRegistry answers "in what order do those parts come up, and in what order do they go down again".
The two are deliberately kept separate: a component’s construction logic lives in its ComponentBuilder, while its startup and shutdown behavior lives in its lifecycle handlers, so that defining a component never forces you to also reason about its place in the startup sequence.
Both registries are reachable from every configurer layer through the componentRegistry(Consumer<ComponentRegistry>) and lifecycleRegistry(Consumer<LifecycleRegistry>) operations described here.
Regardless of which configurer you call these on, be it MessagingConfigurer, ModellingConfigurer, or EventSourcingConfigurer, you are always reaching the same underlying ComponentRegistry and LifecycleRegistry instances, since each configurer wraps the one below it rather than maintaining its own.
The ComponentRegistry
The ComponentRegistry is the registry passed into every ConfigurationEnhancer and made accessible through ApplicationConfigurer#componentRegistry(Consumer).
It exposes the following operations:
| Operation | Purpose |
|---|---|
|
Registers a component under a type, built lazily by the given builder |
|
Registers a component under a type-and-name combination, allowing several components of the same type to coexist |
|
Registers a component from a full |
|
Registers a decorator applied to every component of the given type, invoked at the given order |
|
Registers a decorator applied only to the component matching the given type-and-name combination |
|
Registers a decorator from a full |
|
Checks whether a component of the given type is registered, in this registry or any ancestor |
|
Same check, limited to the current registry, its ancestors, or both |
|
Checks whether a component with the given type-and-name combination is registered, in this registry or any ancestor |
|
Same check, limited to the current registry, its ancestors, or both |
|
Registers a component of the given type only if none is registered yet |
|
Same, with the presence check limited to the given search scope |
|
Registers a component under a type-and-name combination only if none is registered yet |
|
Same, with the presence check limited to the given search scope |
|
Registers a component from a definition only if its type-and-name combination is not yet present |
|
Same, with the presence check limited to the given search scope |
|
Registers an enhancer that can adjust or extend this registry right before the |
|
Registers a |
|
Registers a factory that is consulted to construct a component on demand when no matching component was registered upfront |
|
Sets the policy that dictates what happens when a component is registered under an identifier that is already in use |
|
Disables classpath scanning for enhancers through the |
|
Disables a specific enhancer class from executing during the configuration initialization phase |
|
Same, identifying the enhancer by its fully qualified class name |
The LifecycleRegistry
The LifecycleRegistry is made accessible through ApplicationConfigurer#lifecycleRegistry(Consumer), and is typically used from within a `ComponentDefinition’s or `DecoratorDefinition’s lifecycle hooks, or directly when an application starts up.
It exposes the following operations:
| Operation | Purpose |
|---|---|
|
Configures how long the registry waits for a lifecycle phase to complete before proceeding to the next one |
|
Registers a start handler that runs in the default phase ( |
|
Registers a start handler that runs in the given phase |
|
Registers an asynchronous start handler, providing a future, that runs in the given phase |
|
Registers a start handler with access to the |
|
Registers an asynchronous start handler with access to the |
|
Registers a shutdown handler that runs in the default phase ( |
|
Registers a shutdown handler that runs in the given phase |
|
Registers an asynchronous shutdown handler, providing a future, that runs in the given phase |
|
Registers a shutdown handler with access to the |
|
Registers an asynchronous shutdown handler with access to the |
Start handlers run in ascending phase order; shutdown handlers run in descending phase order.
See component lifecycle for how the Phase constants relate to Axon’s own infrastructure components.