首页 > 解决方案 > 从类路径加载器实例化时具有 null applicationContext 的 Axon SpringBeanParameterResolverFactory

问题描述

10天前我在Axon google群里问过这个问题,但至今没有得到爱。我开始怀疑是否更适合在这里问。我正在尝试将 bean 作为参数注入命令处理程序,但无法弄清楚如何正确使用 SpringBeanParameterResolverFactory。

这是我的聚合配置:

@Bean
public AggregateFactory<ChequeSettingsAggregate> settingsAggregateFactory() {
    return new SpringPrototypeAggregateFactory<>("settingsAggregate");
}

@Bean(name = "settingsAggregateRepository")
public Repository<SettingsAggregate> settingsAggregateRepository(
        EventStore eventStore, SnapshotTriggerDefinition snapshotTriggerDefinition) {

    return new MyEventRepository<>(
            SettingsAggregate.class,
            settingsAggregateFactory(),
            eventStore,
            snapshotTriggerDefinition);
}

MyEventRepository 扩展了 EventSourcingRepository。

这是我的服务:

@Service
@Qualifier("settingsService") // Makes no difference with or without
public class SettingsService extends BaseService { ... }

这是我的汇总:

@Aggregate(repository = "settingsAggregateRepository")
public class SettingsAggregate extends AggregateBase {
    SettingsAggregate() {
        super();
    }

    void handle(UpdateSettingsCommand cmd, @Qualifier("settingsService") SettingsService settingsService) { // Makes no difference without the qualifier.
        settingsService.findOneById(cmd.getId());

        ...
    }
...
}

我得到错误:

nested exception is org.axonframework.messaging.annotation.UnsupportedHandlerException:
 Unable to resolve parameter 1 (SettingsService) in handler void 
    com.domain.settings.api.eventstore.aggregates.SettingsAggregate.handle(
        com.domain.settings.api.eventstore.commands.cheques.UpdateSettingsCommand,
        com.domain.settings.api.services.SettingsService).

SpringBeanResolverFactory 不是 MultiParameterResolverFactory 中的工厂之一。此类的工厂列表由 ClasspathParameterResolverFactory 填充。解析的工厂路径导致参数解析器工厂对象被实例化(不是从 Spring 的 DI 容器自动装配的)。在这段代码运行后的某个时间,SpringBeanResolverFactory 作为 bean 添加到 DI 容器中,这与其他工厂不同(还没有真正深入到弄清楚是什么原因......可能是自动配置)。然而,这个 bean 没有被用作解析器,因为虽然它现在是 bean 应用程序上下文集合的一部分,但它没有添加到 MultiParameterResolverFactory 中的工厂列表中。为了将 SpringBeanResolverFactory 解析器添加到工厂列表中,我添加了一个 org.axonframework.messaging。annotation.ParameterResolverFactory 文件到 META-INF/services 以及解析器的路径。这会将解析器添加到工厂列表中,但没有设置它的 applicationContext 变量,需要拉取我想要作为参数注入的服务。因此,当解析命令处理程序服务参数时,SpringBeanResolverFactory 返回 null,因为它没有设置 applicationContext 字段。

所以,当它不用于解析参数时,我看不到将 SpringBeanResolverFactory 添加到 DI 容器的目的(大概是通过 autoconfig,它设置了 applicationContext 顺便说一句)。如果不设置上下文,我也看不到从类路径实例化 SpringBeanResolverFactory 的目的。

我不确定我在这里缺少什么,但我真的很想弄清楚如何让这个参数注入工作。

在此先感谢,布鲁诺

标签: parametersaggregateresolveraxon

解决方案


问题似乎在于您如何创建 MyEventRepository 实例。如果默认(基于类路径的参数解析器查找)不够用,您需要指定 Axon 如何解析参数。将 添加SpringBeanParameterResolver到类路径解析器列表没有帮助,因为它将在 Spring 上下文之外创建一个实例,并且无法访问 Spring ApplicationContext。

在您的构建器中,您应该传递一个ParameterResolverFactory告诉存储库您希望如何调用该存储库加载的聚合的 a。您应该能够从应用程序上下文中自动装配一个实例,因为 Axon 将注册一个 ParameterResolver,它将自动委托给应用程序上下文中定义的任何其他 ParameterResolver。

更好的解决方案是让 Spring Boot 和 Axon 为您创建一切。您是否有特定的原因要创建自己的 Repository 子类?为什么不保留默认值?

最后一点:Axon 的参数注入机制并非旨在完全替代 Spring 的依赖注入。例如,它不支持@Qualifiers 或InjectionPoints。


推荐阅读