Hi
I tried to inject Spring beans into an aggregate, but failed miserably.
I guess my configuration is not correct.
If I may show you what I did, maybe someone could give me some advices.
I reduced the application to the minimum.
It is a Spring-boot application
Here is my Main class
@Configuration
@EnableAutoConfiguration
@ComponentScan
@Component
class Application {
@Autowired
private MyBean myBean;
@Autowired
private CommandGateway commandGateway;
public static void main(String[] args) {
ConfigurableApplicationContext context = SpringApplication.run(Application.class, args);
Application app = context.getBean(Application.class);
app.greet();
System.exit(0);
}
private void greet() {
System.out.println("Greet: + " + myBean.getMe());
commandGateway.send(new CreateCommand());
}
}
The my Axon config:
@Configuration
class AxonConfig {
@Bean
AnnotationEventListenerBeanPostProcessor annotationEventListenerBeanPostProcessor() {
return new AnnotationEventListenerBeanPostProcessor();
}
@Bean
AnnotationCommandHandlerBeanPostProcessor annotationCommandHandlerBeanPostProcessor() {
return new AnnotationCommandHandlerBeanPostProcessor();
}
@Bean
CommandBus commandBus() {
return new SimpleCommandBus();
}
@Bean
EventBus eventBus() {
return new SimpleEventBus();
}
@Bean
public CommandGatewayFactoryBean<CommandGateway> commandGatewayFactoryBean() {
CommandGatewayFactoryBean<CommandGateway> factory = new CommandGatewayFactoryBean<>();
factory.setCommandBus(commandBus());
return factory;
}
@Bean
public EventSourcingRepository<MyAgg> eventSourcingRepository() {
FileSystemEventStore eventStore = new FileSystemEventStore(new SimpleEventFileResolver(new File("eventstore")));
EventSourcingRepository<MyAgg> repository = new EventSourcingRepository<>(MyAgg.class, eventStore);
repository.setEventBus(eventBus());
return repository;
}
@Bean
public AggregateAnnotationCommandHandler<MyAgg> commandHandler() {
return AggregateAnnotationCommandHandler.subscribe(MyAgg.class, eventSourcingRepository(), commandBus());
}
}
finally my Aggregate
public class MyAgg extends AbstractAnnotatedAggregateRoot {
@AggregateIdentifier
private long id;
MyAgg() {
}
@CommandHandler
public MyAgg(CreateCommand command) throws IOException {
apply(new CreateEvent(new Random().nextInt()));
System.out.println("command ok");
}
@EventHandler
public void id(CreateEvent event, MyBean myBean ) throws IOException {
id = event.getId();
System.out.println("event greets " + myBean.getMe() );
}
}
I omit the Command and the event as they are trivial.
In the CommandHandler as well as in the EventHandler methods of the Aggregate the SpringBean MyBean lead to an exception:
org.axonframework.common.annotation.UnsupportedHandlerException: On method public void
org.axon.sample.inject.bean.MyAgg.id(org.axon.sample.inject.bean.CreateEvent,org.axon.sample.inject.bean.MyBean) throws java.io.IOException, parameter 2 is invalid. It is not of any format supported by a providedParameterValueResolver.
According to the documentation it should be possible to inject beans into an aggregate.
6.2.2
When using Spring and
<axon:annotation-config/> is
declared, any other parameters will resolve to autowired beans, if
exactly one injectable candidate is available in the application
context. This allows you to inject resources directly into
@EventHandler annotated methods. Note that this
only works for Spring-managed beans. Event Sourcing handlers on
Aggregate instances don't get resources injected.
I must confess I'm not sure about the last sentence. "Event Sourcing handlers on
Aggregate instances don't get resources injected."
Do I have this? If so I don't need event sourcing, It is just my first implementation that I want to elaborate on.
Thanks for your help.