Axon Lifecycle: Subscription Handler not registered until late at startup

In a Spring-Boot (standard-ish) setup, we are using a query handler which correctly registers.

I can subscribe using the query gateway just fine if I try to subscribe after the query handlers register.

However (in the context of implementing an bean that requires a subscription query), I get a AXONIQ-5000 error because the bean tries to subscribe to the query early, when the Query Handler has not yet been registered.

I have tried to play with @StartHandler but could not find when I should “hook” into Axon framework’s lifecycle methods, or which event I could subscribe to which guarantees that the queries will be registered properly. The best workaround I have found was a “@Scheduled” method that waits until 5 seconds after startup, which is fine for testing but obviously incorrect, dangerous, and highly coupled to the implementation of query handlers…!

When should I create my bean and/or when should it create its subscription?

Best,
Alexandre

Hi,

you can check the org.axonframework.lifecycle.Phase class. It defines the phases for the various actions an application would need to take to connect. The INBOUND_QUERY_CONNECTOR phase is the one where the query handlers are subscribed. It is indeed rather late, because a component should only allow incoming requests when the rest of the initialization is complete.
If you want to take action during startup, but after query registration, choose at least INBOUND_QUERY_CONNECTOR + 1 as your phase.

To register an action with Axon’s Configuration Lifecycle, there are two ways:

  1. use a @StartHandler annotated method. You will need to register an instance that has this annotated method as a component in your configuration. You can do that using configurer.registerComponent(). Axon doesn’t auto-discover Spring Beans with these annotated methods.
  2. On the Configurer, call onInitialize(config -> config.onStartup(....)); This will ensure your startup method is called in the right phase.
  3. When using Spring boot, you can also just hook into Spring’s lifecycle. If you wait for the application context to have started, Axon will also have been configured properly. The Axon Configuration starts in Spring’s phase 0 (the default phase).

I would recommend using option 3. Any application (Axon or not) that performs certain actions on startup that require initialization of the application itself, should be executed when the application context has successfully started. See https://www.baeldung.com/spring-context-events for more details.

Hope this helps.

To add to Allard’s reply, in Axon Framework 4.6.0 there will be a Spring Event notifying when the Axon Configuration is finalized.
It was a long outstanding issue, which we solved in this pull request.

Thank you so much! I followed your recommendation Allard, and it did work.

Our company is starting to use your framework and we’re finding it a breath of fresh air. Thank you for your work!

3 Likes