Guicey lifecycle events¶
Guicey broadcast lifecycle events in all major points. Each event provides access to all available state at this point.
Events could be used for configuration analysis, reporting or to add some special post processing for configuration items (e.g. post process modules before injector creation).
Important
Event listeners could not modify configuration itself (can't add new extensions, installers, bundles or disable anything).
Events¶
All events are listed in GuiceyLifecycle
enum (in execution order).
Event | Description | Possible usage |
---|---|---|
Dropwizard initialization phase | ||
ConfigurationHooksProcessed? | Called after all registered hooks processing. Not called when no hooks used. | Only for info |
DropwizardBundlesInitialized? | Called after dropwizard bundles initialization (for dropwizard bundles registered through guicey api). Not called if no bundles were registered. | Logging, bundle instances modification (to affect run method) |
BundlesFromLookupResolved? | Called after resolution bundles through lookup mechanism. Not called if no bundles found. | Logging or post processing of found bundles. |
BundlesResolved | Called with all known top-level bundles (transitive bundles are not yet known). Always called to indicate configuration state. | Could be used to modify top-level bundle instances |
BundlesInitialized? | Called after all bundles initialization (including transitive, so list of bundles could be bigger). Not called when no bundles registered. | Logging, post processing |
CommandsResolved? | Called if commands search is enabled and at least one command found | Logging |
InstallersResolved | Called when all configured (and resolved by classpath scan) installers initialized | Potentially could be used to configure installer instances |
ManualExtensionsValidated? | Called when all manually registered extension classes are recognized by installers (validated). But only extensions, known to be enabled at that time are actually validated (this way it is possible to exclude extensions for non existing installers). Called only if at least one manual extension registered. | Logging, assertions |
ClasspathExtensionsResolved? | Called when classes from classpath scan analyzed and all extensions detected (if extension is also registered manually it would be also counted as from classpath scan). Called only if classpath scan is enabled and at least one extension detected. | Logging, assertions |
Initialized | Meta event, called after GuiceBundle initialization (most of configuration done). Pure marker event, indicating guicey work finished under dropwizard configuration phase. | Last chance to modify Bootstrap |
Dropwizard run phase | ||
BeforeRun | Meta event, called before any guicey actions just to indicate first point where Environment, Configuration and introspected configuration are available | For example, used by bundle.printConfigurationBindings() to print configuration bindings before injector start (help with missed bindings debug) |
BundlesStarted? | Called after bundles start (run method call). Not called if no bundles were used at all. Called only if bindings analysis is not disabled. | Logging |
ModulesAnalyzed | Called after guice modules analysis and repackaging. Reveals all detected extensions and removed bindings info. | Logging, analysis validation logic |
ExtensionsResolved | Called to indicate all enabled extensions (manual, from classpath scan and modules). Always called to indicate configuration state. | Logging or remembering list of all enabled extensions (classes only) |
InjectorCreation | Called just before guice injector creation. Provides all configured modules (main and override) and all disabled modules. Always called. | Logging. Note that it is useless to modify module instance here, because they were already processed. |
Guice injector created | ||
ExtensionsInstalledBy | Called when installer installed all related extensions (for each installer) and only for installers actually performed installations (extensions list never empty). Note: jersey extensions are processed later. | Logging of installed extensions. Extension instance could be obtained from injector and post processed. |
ExtensionsInstalled? | Called after all installers install related extensions. Not called when no installed extensions (nothing registered or all disabled) | Logging or extensions post processing |
ApplicationRun | Meta event, called when guice injector started, extensions installed (except jersey extensions because neither jersey nor jetty would be started yet) and all guice singletons initialized. At this point injection to registered commands is performed (this may be important if custom command run application instead of "server"). Point is just before Application.run method. |
Ideal point for jersey and jetty listeners installation (with shortcut methods in event). |
Jersey initialization | ||
JerseyConfiguration | Jersey context starting. Both jersey and jetty are starting. | First point where jersey's InjectionManager (and ServiceLocator ) become available |
JerseyExtensionsInstalledBy | Called when jersey installer installed all related extensions (for each installer) and only for installers actually performed installations (extensions list never empty) | Logging of installed extensions. Extension instance could be obtained from injector/locator and post processed. |
JerseyExtensionsInstalled? | Called after all jersey installers install related extensions. Not called when no installed extensions (nothing registered or all disabled). At this point HK2 is not completely started yet (and so extensions) | Logging or extensions post processing |
ApplicationStarted | Meta event, called after complete dropwizard startup. This event also will be fired in guicey lightweight tests | May be used as assured "started" point (after all initializations). For example, for reporting. |
ApplicationShutdown | Meta event, called on server shutdown start. This event also will be fired in guicey lightweight tests | May be used for shutdown logic. |
ApplicationStoppedEvent | Meta event, called after application shutdown. This event also will be fired in guicey lightweight tests | May be used in rare cases to cleanup fs resources after application stop. |
? - event may not be called
Listeners¶
Events listener registration:
GuiceBundle.builder()
.listen(new MyListener(), new MyOtherListener())
...
.build()
Note
Listeners could be also registered in guicey bundle, but they will not receive all events:
>= BundlesInitialized
for listeners registered in initialization method>= BundlesStarted
for listeners registered in run method
Event listener could implement generic event interface GuiceyLifecycleListener
and use
enum to differentiate required events:
public class MyListener implements GuiceyLifecycleListener {
public void onEvent(GuiceyLifecycleEvent event) {
switch (event.getType()) {
case InjectorCreation:
InjectorCreationEvent e = (InjectorCreationEvent) event;
...
}
}
}
Or use GuiceyLifecycleAdapter
adapter and override only required methods:
public class MyListener extends GuiceyLifecycleAdapter {
@Override
protected void injectorCreation(final InjectorCreationEvent event) {
...
}
}
Tip
In ApplicationStarted
and ApplicationShutdown
events lightweight guicey test
environment may be differentiated from real server startup with .isJettyStarted()
method.
De-duplication¶
Event listeners are also support de-duplication to prevent unnecessary duplicates usage (for example, two bundles may register one listener because they are not always used together). But it is not the same mechanism as configuration items de-duplication.
Simply listeners are registered in the LinkedHashSet
and so listeners could control de-duplication
with a proper equals
and hashCode
implementations
Many reports use this feature (because all of them are based on listeners). For example, diagnostic report use the following implementations:
@Override
public boolean equals(final Object obj) {
// allow only one instance with the same title
return obj instanceof ConfigurationDiagnostic
&& reportTitle.equals(((ConfigurationDiagnostic) obj).reportTitle);
}
@Override
public int hashCode() {
return reportTitle.hashCode();
}
And with it, .printDiagnosticInfo()
can be called multiple times and still only one report
will be actually printed.
Events hierarchy¶
All event classes inherit from some base event classes. Base event classes are extending each other: as lifecycle phases go, more objects become available. So you can access any available (at this point) object from event instance.
Base event | Description |
---|---|
GuiceyLifecycleEvent | The lowest event type. Provides access to event type and options. |
ConfigurationPhaseEvent | Initialization phase event. Provides access to Bootstrap. |
RunPhaseEvent | Dropwizard run phase. Provides access to Configuration, ConfigurationTree, Environment. Shortcut for configuration bindings report renderer |
InjectorPhaseEvent | Guice injector created. Available injector and GuiceyConfigurationInfo (guicey configuration). Shortcuts for configuration reports renderer |
JerseyPhaseEvent | Jersey starting. Jersey's InjectionManager available. |