The AxonFramework has many integration points with the Spring Framework. All major building blocks in Axon are Spring configurable. Furthermore, there are some Bean Post Processors that scan the application context for building blocks and automatically wires them.
Axon uses JSR 250 annotations (@PostConstruct
and @PreDestroy
)
to annotate lifecycle methods of some of the building blocks. Spring doesn't always
automatically evaluate these annotations. To force Spring to do so, add the
<context:annotation-config/>
tag to your application context, as shown
in the example
below:
<beans xmlns="http://www.springframework.org/schema/beans" xmlns:context="http://www.springframework.org/schema/context"> <context:annotation-config/> </beans>
Using the annotated event listeners is very easy when you use Spring. All you need to
do is configure the AnnotationEventListenerBeanPostProcessor
in your
application context. This post processor will discover beans with @EventHandler
annotated methods and automatically connect them to the event bus.
<beans xmlns="http://www.springframework.org/schema/beans"> <bean class="org...AnnotationEventListenerBeanPostProcessor"><property name="eventBus" ref="eventBus"/>
</bean> <bean class="org.axonframework.sample.app.query.AddressTableUpdater"/>
</beans>
![]() |
This bean post processor will scan the application context for beans
with an |
![]() |
The reference to the event bus is optional, if only a single
|
![]() |
This event listener will be automatically recognized and subscribed to the event bus. |
You can also wire event listeners "manually", by explicitly defining them within a
AnnotationEventListenerAdapter
bean, as shown in the code sample below.
<beans xmlns="http://www.springframework.org/schema/beans"> <bean class="org.axonframework...annotation.AnnotationEventListenerAdapter"><constructor-arg> <bean class="org.axonframework.sample.app.query.AddressTableUpdater"/> </constructor-arg> <property name="eventBus" ref="eventBus"/>
</bean> </beans>
![]() |
The adapter turns any bean with |
![]() |
You need to explicitly reference the event bus to which you like to register the event listener |
![]() | Warning |
---|---|
Be careful when wiring event listeners "manually" while there is also an
|
In a typical Axon application, there is only one event bus. Wiring it is just a matter
of creating a bean of a subtype of EventBus
. The
SimpleEventBus
is the provided implementation.
<beans xmlns="http://www.springframework.org/schema/beans"> <bean id="eventBus" class="org.axonframework.eventhandling.SimpleEventBus"/> </beans>
The command bus doesn't take any configuration to use. However, it allows you to configure a number of interceptors that should take action based on each incoming command.
<beans xmlns="http://www.springframework.org/schema/beans"> <bean id="eventBus" class="org.axonframework.commandhandling.CommandBus"> <property name="interceptors"> <list> <bean class="org.axonframework...SpringTransactionalInterceptor"> <property name="transactionManager" ref="transactionManager"/> </bean> <bean class="other-interceptors"/> </list> </property> </bean> </beans>
Wiring a repository is very similar to any other bean you would use in a Spring application. Axon only provides abstract implementations for repositories, which means you need to extend one of them. See Chapter 5, Repositories and Event Stores for the available implementations.
Repository implementations that do support event sourcing just need the event bus to be configured, as well as any dependencies that your own implementation has.
<bean id="simpleRepository" class="my.package.SimpleRepository"> <property name="eventBus" ref="eventBus"/> </bean>
Repositories that support event sourcing will also need an event store, which takes
care of the actual storage and retrieval of events. The example below shows a repository
configuration of a repository that extends the
EventSourcingRepository
.
<bean id="contactRepository" class="org.axonframework.sample.app.command.ContactRepository"> <property name="eventBus" ref="eventBus"/> <property name="eventStore" ref="eventStore"/> </bean>
In many cases, you can use the GenericEventSourcingRepository
. Below is
an example of XML application context configuration to wire such a repository.
<bean id="myRepository" class="org.axonframework.eventsourcing.GenericEventSourcingRepository"> <constructor-arg value="fully.qualified.class.Name"/> <property name="eventBus" ref="eventBus"/> <property name="eventStore" ref="eventStore"/> </bean>
The repository will delegate the storage of events to the configured
eventStore
, while these events are dispatched using the provided
eventBus
.
All event sourcing repositorties need an event store. Wiring the
JpaEventStore
and the FileSystemEventStore
is very
similar, but the JpaEventStore
needs to run in a Spring managed
transaction. Unless you use the SpringTransactionalInterceptor
on your
command bus, you need to declare the annotation-driven transaction-manager as shown in
the sample below.
<bean id="eventStore" class="org.axonframework.eventstore.jpa.JpaEventStore"/> <!-- enable the configuration of transactional behavior based on annotations --> <tx:annotation-driven transaction-manager="txManager"/> <!-- declare transaction manager, data source, EntityManagerFactoryBean, etc -->