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 commandGatewayFactoryBean() {
CommandGatewayFactoryBean factory = new CommandGatewayFactoryBean<>();
factory.setCommandBus(commandBus());
return factory;
}
@Bean
public EventSourcingRepository eventSourcingRepository() {
FileSystemEventStore eventStore = new FileSystemEventStore(new SimpleEventFileResolver(new File(“eventstore”)));
EventSourcingRepository repository = new EventSourcingRepository<>(MyAgg.class, eventStore);
repository.setEventBus(eventBus());
return repository;
}
@Bean
public AggregateAnnotationCommandHandler 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.