MessageDispatchInterceptor
which logs each command message being dispatched on a CommandBus
.CommandBus
by doing the following:@NotEmpty
and @Pattern
. You need to include a JSR 303 implementation (such as Hibernate-Validator) on your classpath. Then, configure a BeanValidationInterceptor
on your command bus, and it will automatically find and configure your validator implementation. While it uses sensible defaults, you can fine-tune it to your specific needs.Interceptor Ordering TipYou want to spend as few resources on an invalid command as possible. Therefore, this interceptor is generally placed at the very front of the interceptor chain. In some cases, aLoggingInterceptor
orAuditingInterceptor
might need to be placed first, with the validating interceptor immediately following it.
BeanValidationInterceptor
also implements MessageHandlerInterceptor
, allowing you to configure it as a handler interceptor as well.MessageHandlerInterceptor
interface. This interface declares one method, handle
, that takes two parameters: the current UnitOfWork
and an InterceptorChain
. The InterceptorChain
is used to continue the dispatching process. The UnitOfWork
gives you (1) the message being handled and (2) provides the possibility to tie in logic prior, during or after (command) message handling (see Unit Of Work for more information about the phases).TransactionManagingInterceptor
, which in turn is configured with a TransactionManager
to start and commit (or roll back) the actual transaction.axonUser
as a value for the userId
field in the MetaData
. If the userId
is not present in the metadata, an exception will be thrown which will prevent the command from being handled. Additionally, if the value of userId
does not match axonUser
, we will also not proceed up the chain.CommandBus
like so:@CommandHandlerInterceptor
Annotation@CommandHandlerInterceptor
annotated method on the Aggregate/Entity. The difference between a method on an Aggregate and a "regular" Command Handler Interceptor, is that with the annotation approach you can make decisions based on the current state of the given Aggregate. Some properties of an annotated Command Handler Interceptor are:InterceptorChain
as a parameter of the command handler interceptor method and use it to control command execution.commandNamePattern
attribute of the @CommandHandlerInterceptor
annotation we can intercept all commands matching the provided regular expression.@CommandHandlerInterceptor
annotated method which prevents command execution if a command's state
field does not match the Aggregate's state
field:@CommandHandlerInterceptor
is essentially a more specific implementation of the @MessageHandlerInterceptor
described here.EventBus
.EventBus
by doing the following:MessageHandlerInterceptor
interface. This interface declares one method, handle()
, that takes two parameters: the current UnitOfWork
and an InterceptorChain
. The InterceptorChain
is used to continue the dispatching process. The UnitOfWork
gives you (1) the message being handled and (2) provides the possibility to tie in logic prior, during or after (event) message handling (see Unit Of Work for more information about the phases).axonUser
as the value for the userId
field in the MetaData
. If the userId
is not present in the metadata, an exception will be thrown which will prevent the Event from being handled. And if the value of userId
does not match axonUser
, we will also not proceed up the chain. Authenticating the event message like shown in this example is a regular use case of the MessageHandlerInterceptor
.EventProcessor
like so:Interceptor RegistrationDifferent from theCommandBus
andQueryBus
, which both can have handler interceptors and dispatch interceptors, theEventBus
can only register dispatch interceptors. This is because the sole purpose of theEventBus
is event publishing/dispatching, thus they are where event dispatch interceptors are registered.EventProcessor
s are in charge of handling event messages, thus they are where event handler interceptors are registered.
@NotEmpty
and @Pattern
. You need to include a JSR 303 implementation (such as Hibernate-Validator) on your classpath. Then, configure a BeanValidationInterceptor
on your query bus, and it will automatically find and configure your validator implementation. While it uses sensible defaults, you can fine-tune it to your specific needs.Interceptor Ordering TipYou want to spend as few resources on an invalid queries as possible. Therefore, this interceptor is generally placed at the very front of the interceptor chain. In some cases, a logging or auditing interceptor might need to be placed first, with the validating interceptor immediately following it.
BeanValidationInterceptor
also implements MessageHandlerInterceptor
, allowing you to configure it as a handler interceptor as well.MessageHandlerInterceptor
interface. This interface declares one method, handle
, that takes two parameters: the current UnitOfWork
and an InterceptorChain
. The InterceptorChain
is used to continue the dispatching process. The UnitOfWork
gives you (1) the message being handled and (2) provides the possibility to tie in logic prior, during or after (query) message handling (see Unit Of Work for more information about the phases).MessageHandlerInterceptor
instances on the component handling a message (e.g. a command, query or event), it is also possible to define a handler interceptor for a specific component containing the handlers. This can be achieved by adding a method handling the message, combined with the @MessageHandlerInterceptor
annotation. Adding such a method allows you more fine-grained control over which message handling components should react and how these should react.@MessageHandlerInterceptor
, like:MessageHandlerInterceptor
instances work with the InterceptorChain
to decide when to proceed with other interceptors in the chain. The InterceptorChain
is an optional parameter which can be added to the intercepting method to provide you with the same control. In absence of this parameter, the framework will call InterceptorChain#proceed
once the method is exited.Message
the interceptor should deal with. By default, it reacts to any Message
implementation. If an EventMessage
specific interceptor is desired, the messageType
parameter on the annotation should be set to EventMessage.class
.payloadType
contained in the Message
to handle can be specified.@MessageHandlerInterceptor
annotation:InterceptorChain
, a @MessageHandlerInterceptor
annotated method can resolve other parameters as well. Which parameters the framework can resolve on such a function, is based on the type of Message
being handled by the interceptor. For more specifics on which parameters are resolvable for the Message
being handled, take a look at this page.@MessageHandlerInterceptor
also allows for a more specific version of an intercepting function. Namely, an @ExceptionHandler
annotated method.@ExceptionHandler
annotated methods only for exceptional results of message handling. Using exception handlers like this, for example, allows you to throw more domain-specific exceptions as a result of a thrown database/service exception. Or, you can catch an aggregate-specific exception and translate it to a generic error code.MetaData
, and other options to the @ExceptionHandler
annotated function.@ExceptionHandler
annotated methods in any message handling component. Furthermore, you can choose to react to all exceptions or define specific exception/message combinations to which the handler should respond. Check the following samples for some snippets on how to use this:Exception Handling for Aggregate ConstructorsThe@ExceptionHandler
annotated methods require an existing component instance to work. Because of this, exception handlers do not work for (command handling) constructors of an aggregate.If you thus expect exceptions on an aggregate's command handler that you need to handle differently, it is recommended to use Axon's creation policy.