Inject Spring Bean in Aggregate @EventSourcedHandler

611 views
Skip to first unread message

Roscoe Lotriet

unread,
Sep 14, 2014, 2:40:49 PM9/14/14
to axonfr...@googlegroups.com
Hi all,

What is the correct means to inject Spring beans into my Aggregate @EventSourcedHandler methods? I am aware of the registerParameterResolverFactory method on the aggregate but am not sure when & how to register the SpringBeanParameterResolver.

@CommandHandler methods are injected successfully & are configured via AnnotationCommandHandlerFactoryBean.

My aggregate @EventSourcedHandler methods are not called on applying events within a @CommandHandler.

I am injecting Spring Beans into all @CommandHandler & @EventSourcedHandler methods.

Cheers,
Roscoe

Allard Buijze

unread,
Sep 15, 2014, 4:34:46 AM9/15/14
to Axon Framework Users
Hi Roscoe,

there seems to be an issue with Spring bean injection in @Event(Sourcing)Handler. It's recorded under AXON-265.
I'll let you know once it's fixed.

Cheers,

Allard


--
You received this message because you are subscribed to the Google Groups "Axon Framework Users" group.
To unsubscribe from this group and stop receiving emails from it, send an email to axonframewor...@googlegroups.com.
For more options, visit https://groups.google.com/d/optout.

Allard Buijze

unread,
Sep 15, 2014, 2:47:24 PM9/15/14
to Axon Framework Users
Hi Roscoe,

how did you define the EventSourcingRepository in the Spring context? If you use the namespace support (axon:event-sourcing-repository), it defaults to a parameter resolver factory that also looks at Spring beans. However, a Spring bean is only eligible for autowiring if only a single bean of the specified type is available. Otherwise, another parameter resolver should provide a value.

Regarding the code generation, I'm not totally convinced that using separate "EventHandler"s and "ValidationSpec"s are really going to make aggregate design fundamentally easier. One will end up with many more classes, that unless they are completely generated and maintained from some UI, will complicate things more than they simplify. One of the situations, for example is where a single command generates multiple events in between, where subsequent events depend on the state after the first is applied. I don't see how the current design/implementation could handle these events. Maybe it's just my reluctance when it comes to code generation.

Cheers,

Allard

On Mon, Sep 15, 2014 at 11:24 AM, Roscoe Lotriet <rlotr...@gmail.com> wrote:
Hi Allard,

Thanks for your response I look forward to your feedback.

Here is a heads up on what I am attempting, your input would be appreciated:

I am writing a tool to generate domain model code, including Commands, Events & ARs.
It is still in a foundation phase at the moment & consists of a JSON model definition that generates AXON code.
The JSON file:

{
"apiPackage" : "com.zailab.user.domain.model.user.api.",
"aggregateRoot" : "User",
"aggregateIdentifier" : "UserId",
"commands" :   [{
"name" : "RegisterUser",
"constructorCommandHandler"  : "true",
"properties" : [
"userId", "username", "password", "confirmPassword", "email", "firstName", "surname"
],
"appliedEvents" : 
[{
"name" : "UserRegistered",
"properties" : [
"userId", "username", "password", "email", "firstName", "surname"
]
}]
}]
}

This results in the Commands, Event & AR code. The commands handler methods are of the format:

    @CommandHandler
    public User(RegisterUserCommand registerUserCommand, RegisterUserValidationSpec commandValidationSpec) {
        if (commandValidationSpec.isSatisfiedBy(registerUserCommand)) {
            apply(new UserRegisteredEvent(registerUserCommand.getUserId(), registerUserCommand.getUsername(), registerUserCommand.getPassword(), registerUserCommand.getEmail(), registerUserCommand.getFirstName(), registerUserCommand.getSurname()));
        } else {
            throw new ValidationException(("Could not process "+ registerUserCommand));
        }
    }

The validation spec is injected at runtime & is a @Component implementation of the RegisterUserValidationSpec, therefore decoupling validation code from the AR. This works perfectly via the AggregateAnnotationCommandHandlerFactoryBean.

I would like to do the same for aggregate event handler methods, and inject a event handler like:

    @EventSourcingHandler
    public void handle(UserRegisteredEvent event, UserRegisteredEventHandler eventHandler) {
         eventHandler.handle(event, this);
    }

The eventHandler would also be injected at runtime via a @Component implementation, thereby decoupling the event handling code from the AR as well.
Entities & AR properties could then be manipulated in the eventHandler.
The domain model could then be constantly scaffolded/regenerated from the model definition in the JSON file without overwriting command & event handling implementations.
I would like to eventually add a UI to assist with modelling the domain & store the definition in a DB.

Your thoughts on my attempt would be greatly appreciated.

Regards,
Roscoe Lotriet

Roscoe Lotriet

unread,
Sep 16, 2014, 2:02:48 AM9/16/14
to axonfr...@googlegroups.com
Hi Allard,

Thanks for your feedback, much appreciated.
I'm using Spring Boot & JavaConfig, declaring the repository as such:

    @Bean
    @Autowired
    Repository<com.zailab.user.domain.model.user.api.User> repository(EventStore eventStore, EventBus eventBus)
        throws Exception
    {
        EventSourcingRepository<com.zailab.user.domain.model.user.api.User> repository = new EventSourcingRepository<com.zailab.user.domain.model.user.api.User>(com.zailab.user.domain.model.user.api.User.class, eventStore);
        repository.setEventBus(eventBus);
        return repository;
    }

Thanks for your feedback on the implementation, I will take all points into consideration. The end goal is to have the aggregate designed in a UI & be flexible, we'll see if that is achievable :) For now it's more of a scaffolding tool for axon apps.

Any feedback on the @EventSourcingHandler issue would be appreciated.

Cheers,
Roscoe

Roscoe Lotriet

unread,
Sep 18, 2014, 4:38:59 AM9/18/14
to axonfr...@googlegroups.com
As addition to the above question, can Spring beans be injected into AbstractAnnotatedEntity @Event(Sourcing)Handler methods?

Cheers,
Roscoe

Allard Buijze

unread,
Sep 18, 2014, 4:56:16 AM9/18/14
to Axon Framework Users
Hi Roscoe,

once AXON-265 is fixed, that will definitely be possible. If you don't use the (xml) namespace support, there is a littlebit of configuration you need to add. As soon as the fix is done, I will let you know what that is.

Cheers,

Allard

--

Roscoe Lotriet

unread,
Sep 18, 2014, 5:12:42 AM9/18/14
to axonfr...@googlegroups.com
Hi Allard,

Thanks again.

Cheers,
Roscoe

Roscoe Lotriet

unread,
Oct 8, 2014, 10:26:12 AM10/8/14
to axonfr...@googlegroups.com
Hi Allard,

I see this is now working in Axon 2.3.2 :)

Regards,
Reply all
Reply to author
Forward
0 new messages