我正在尝试使用Spring Boot和Akka。我有两个过程,并与akka集群进行通信。仅进程A使用Spring Boot。

@Autowired
private ActorSystem springActorSystem;

@Autowired
private SpringExtension springExtension;

private ActorRef caActor;
caActor = springActorSystem.actorOf(springExtension.props("clientAgentActor"), "ca");


如果我在进程A上创建actor,当然使用springExtension,则所有注入都有效。但是,caActor是群集参与者。如果进程B向进程A发送消息,则ClientAgentActor在某处被调用,则所有注入都会失败。
怎么解决呢?

@Component
@Scope(ConfigurableBeanFactory.SCOPE_PROTOTYPE)
public class ClientAgentActor extends AbstractActor {

private static final Logger logger = LogManager.getLogger(ClientAgentActor.class);

@Autowired
ClientAgentService caService;

@Autowired
LineService lineService;

@Override
public Receive createReceive() {
    //TODO
    return receiveBuilder().match(String.class, msg -> logger.debug(msg)).build();
}

最佳答案

几乎整天都这么认为。而且我认为,如果不更改Akka Cluster的核心,就无法将Spring与具有完整DI的Akka群集进行跨群集调用。

当您在一个JVM中进行无群集调用时,您将使用Akka包装器而不是纯Akka。
但是,当您在集群中进行调用时,没有Spring包装程序的纯Akka基础结构会在其他节点上收到此调用,因此该基础结构不了解Spring actor代理,这就是为什么您看不到注入的原因。

因此,如果您需要Akka Cluster中的Spring,则需要使用Spring基础结构包装该库的核心。除非实现起来不容易,否则在应用程序体系结构中遵循Akka规则和约定也很困难。例如,注入具有阻塞调用或多线程代码的传递依赖关系太容易了。

如果您需要使用某些Spring功能,我认为最好的方法是将Akka基础架构与Spring的基础架构完全分开。在应用程序初始化之后,使用创建的ApplicationContext设置全局静态字段,并在需要它们的地方进行applicationContext.getBean(...)调用。当然,您可以为此选择舒适的方法。或例如,带有带有必需bean的公共静态字段的类,在Spring初始化完成后设置一次。

09-16 04:58