Executor
s, meaning that you can easily pass a container managed Thread Pool, for example. If you don't use a full blown Application Server (e.g. Tomcat, Jetty or a stand-alone app), you can use the Executors
class or the Spring Framework to create and configure Thread Pools.IssuedEvt
:RedeemCmd
(do note that amount
is amount to be deducted from the Giftcard) and RedeemEvt
:@TargetAggregateIdentifier
annotation is used by Axon to find the correct Giftcard aggregate instance.Defined commands and events do not haveequals/hashCode/toString
methods overriden since our example would be lengthy. However, it is highly recommended to do so due to testing/debugging/auditing reasons.
@AggregateIdentifier
annotation tells Axon that annotated field will be used as identifier of the Aggregate.IssueCmd
is dispatched, annotated constructor will be invoked.AggregateLifecycle.apply
method will apply method on given aggregate (@EventSourcingHandler
matching this event will be called on aggregate), and then it will be published to the EventBus
, so other components can react upon it.Note All business logic / rules are defined in the@CommandHandler
s, and all state changes are defined in the@EventSourcingHandler
s. The reason for this is when we want to get the current state of event-sourced Aggregate, we have to apply all sourced events - we have to invoke@EventSourcingHandler
s. If the state of our Aggregate is changed outside of@EventSourcingHandler
s it will not be reflected when we do a replay.
List
Java structure as our storage. The CardSummary
class could look like this:IssuedEvt
is published, this method will be invoked. For more details check event handling.EventHandlingConfiguration
and as a query handler (4)Note If you are using Spring, none of these configuration steps are required if you markGiftCard
aggregate with@Aggregate
annotation andCardSummaryProjection
as Spring@Component
.
CommandGateway
and QueryGateway
from configuration: