Search code examples
dependenciescode-injectionaxon

AxoniQ how to configure SpringBeanParameterResolverFactory as part of MultiParameterResolverFactory for spring beans to dependecy inject


This might be a simple one, but I have tried all the axon blogs and did not find exact configuration in how to configure the SpringBeanParameterResolverFactory as part of the delegated list of MultiParameterResolverFactory.

ExternalService.java

@Component
public class ExternalService {

    public void testcall(){
        System.out.println("test operation called");
    }
}

pom.xml

<axon.version>4.5</axon.version>

...
...

  <dependency>
            <groupId>org.axonframework</groupId>
            <artifactId>axon-spring-boot-starter</artifactId>
            <version>${axon.version}</version>
        </dependency>

Inside Aggregate class

  @CommandHandler
    public GiftCard(IssueCmd cmd, ExternalService externalService) {
        externalService.handle();

        logger.debug("handling {}", cmd);
        if (cmd.getAmount() <= 0) {
            throw new IllegalArgumentException("amount <= 0");
        }
        apply(new IssuedEvt(cmd.getId(), cmd.getAmount()));
    }

But at runtime, I am getting below exception

Caused by: org.axonframework.messaging.annotation.UnsupportedHandlerException: Unable to resolve parameter 1 (ExternalService) in handler public io.axoniq.demo.giftcard.command.GiftCard(io.axoniq.demo.giftcard.api.IssueCmd,io.axoniq.demo.giftcard.service.ExternalService).
    at org.axonframework.messaging.annotation.AnnotatedMessageHandlingMember.<init>(AnnotatedMessageHandlingMember.java:76) ~[axon-messaging-4.5.jar:4.5]
    at org.axonframework.messaging.annotation.AnnotatedMessageHandlingMemberDefinition.lambda$createHandler$0(AnnotatedMessageHandlingMemberDefinition.java:51) ~[axon-messaging-4.5.jar:4.5]
...
...

Also checked the MultiparameterresolverFactory and is the list its not showing the SpringBeanParameterResolverFactory.

enter image description here

Request for the help. Thanks in advance.


Solution

  • Would you be able to elaborate on why you need to configure the ParameterResolver yourself? Normally, this isn't needed at all, especially not for the SpringBeanParameterResolverFactory as it will be auto-configured for you.

    Simply provided the ExternalService in your application context, by either annotating it directly or by having a bean creation method should suffice.


    If you do need to add additional ParameterResolverFactory instances, the following approaches should be sufficient to automatically attach them to the used MultiParameterResolverFactory without your interference:

    • Adding the fully qualified class name of your ParameterResolverFactory to a file called org.axonframework.messaging.annotation.ParameterResolverFactory inside your resources/META-INF/services folder. Axon uses the Service Loader approach to load them, which means you can attach to this if needed.
    • When in a Spring environment, you can simply annotate your custom ParameterResolverFactory with @Component and the framework will pick it up. So simply put, if you add it to your Application Context, Axon can find it.
    • You can override Axon's ParameterResolverFactory entirely by registering it as a component to the Configuration API. To that end, you would use the Configurer#registerComponent(Class<C>, Function<Configuration, ? extends C>) method. Note that this will require you to provide the MultiParameterResolverFactory as apposed to the previous two options.