当前位置: 首页 > 知识库问答 >
问题:

如何为Spring编写Akka类型扩展以进行构造函数依赖注入?

钱和安
2023-03-14

在Akka 2.6之前,或者使用经典Actors,可以编写一个Akka扩展来访问Akka非类型化Actor中Spring的@Inject注释。

其中一个例子是:https://github.com/typesafehub/activator-akka-java-spring/blob/master/src/main/java/sample/SpringExtension.java

然而,这不适用于新的Akka类型的演员。

Akka的文档没有显示如何进行这样的扩展(但它显示了如何进行简单的扩展:https://doc.akka.io/docs/akka/current/typed/extending.html#building-扩展)。

到目前为止,我写了这个扩展的开头,但我不知道如何将Spring的ApplicationContext与actor系统链接起来:

import org.springframework.context.ApplicationContext;

import akka.actor.typed.ActorSystem;
import akka.actor.typed.Extension;
import akka.actor.typed.ExtensionId;

public class SpringExtension implements Extension {

  private volatile ApplicationContext applicationContext;

  private SpringExtension(final ActorSystem<?> system) {
    // TODO: What do you put here?
  }

  void initialize(final ApplicationContext applicationContext) {
    this.applicationContext = applicationContext;
  }

  public static class Id extends ExtensionId<SpringExtension> {

    private static final Id instance = new Id();

    private Id() {}

    // called once per ActorSystem
    @Override
    public SpringExtension createExtension(final ActorSystem<?> system) {
      return new SpringExtension(system);
    }

    public static SpringExtension get(final ActorSystem<?> system) {
      return instance.apply(system);
    }
  }
}

如何为类型化演员编写允许在类型化演员中使用Spring DI的Akka扩展?

共有1个答案

咸昀
2023-03-14

可能这并不完全是您所需要的,但我认为找到了一种方法,可以在不使用扩展的情况下注入类型化的参与者。

我们可以将行为创建为bean,注入所有需要的依赖项并将其传递给另一个参与者,在那里根据定义的行为生成参与者。

假设我们有PrintActor,它可以使用PrintService打印消息,GreetActor使用GreetService生成PrintActor。我们可以这样定义bean:

@Bean
public Behavior<String> printActorBehavior(PrintService printService) {
    return Behaviors.setup(ctx -> new PrintActor(ctx, printService));
}

@Bean
public Behavior<GreetActor.Greet> greetActorBehavior(GreetService greetService, 
                                                     Behavior<String> printerActorBehavior) {
    return Behaviors.setup(ctx -> new GreetActor(ctx, greetService, printerActorBehavior));
}

然后,在GreetActor中,我们只需通过调用getContext(). spawn(printerActorBeAct or,“打印机”)从注入的行为创建行为者;

public class GreetActor extends AbstractBehavior<GreetActor.Greet> {
    private GreetService greetService;
    private Behavior<String> printerActorBehavior;

    public GreetActor(ActorContext<Greet> context, 
                      GreetService greetService,
                      Behavior<String> printerActorBehavior) {
        super(context);
        this.greetService = greetService;
        this.printerActorBehavior = printerActorBehavior;
    }

    @Override
    public Receive<Greet> createReceive() {
        return newReceiveBuilder()
                .onMessage(Greet.class, this::onGreet)
                .build();
    }

    private Behavior<Greet> onGreet(Greet msg) {
        ActorRef<String> printer = getContext().spawn(printerActorBehavior, "printer");
        printer.tell(greetService.greet(msg.name));
        return this;
    }

    @Value
    static class Greet {
        String name;
    }
}

因为我们不能在Akka类型的actor系统之外创建actor,所以我认为没有合适的方法将ActorRef注入Spring。

我们可以尝试将Spring上下文注入到参与者中,生成一些参与者并将它们放入Spring上下文中,但我认为这不是同时使用两个框架的好方法。

 类似资料:
  • 好的,到目前为止还好。但是等等,突然A需要额外的输入,比如一个对它的构造至关重要的名为“amount”的整数。现在,我的A构造函数需要如下所示: 突然这个新参数干扰了注射。此外,即使这确实有效,我也无法在从提供者检索新实例时输入“金额”,除非我弄错了。这里有几件事我可以做,我的问题是哪一件是最好的? 我可以通过添加一个方法来重构A,该方法应该在构造函数之后调用。然而,这是很难看的,因为它迫使我推迟

  • 和另一个类: 在这种情况下,服务将按照预期注入到A类中。据我所知,你不能在a类中使用构造函数,否则注入将无法工作。有没有一种方法可以在a类中使用一个构造函数,同时注入服务?即: 在这种情况下,我得到的服务是空的,无论如何要解决这个问题?我希望能够从类型A中使用“new”创建一个对象,并注入服务,这可能吗?

  • 我正试图在计算机上实现这个例子https://developer.android.com/jetpack/docs/guide.这就解释了Android应用程序的结构。 当我使用相同的代码时,我会出现以下错误。 我可以找出这个错误与 当我为ViewModel编写默认的零输入构造函数时,我得到了以下错误。 我想不出这个错误的原因和解决方法。

  • 我是新手。所以我想在我的使用MVVM架构的项目上尝试依赖注入。结构如下:JsonHelper- 当我试图在RemoteDataSource和Repository上注入DI时,出现了问题,因为这些类是单例类,并且有一个私有构造函数。错误代码如下所示 这是我的远程数据源和存储库代码,我已经尝试将其注入构造函数,但它说Dagger不能注入私有构造函数,所以我尝试将其注入函数,但仍然不起作用 远程数据源.

  • 我需要重构现有的抽象类来实现依赖注入,但是这个类有两个接受其他参数的构造函数。 我需要注入一些接口,并避免在构造函数中传递任何其他参数,如“settingsId”和“Setting”。所以我的想法是在创建此类的实例后创建两种方法来设置这些参数。 但它看起来不是一个合适的解决方案,因为如果开发人员忘记在创建实例后运行这些方法之一,我们将来可能会得到一个异常(对象未设置为引用...)。我应该如何正确执

  • 问题内容: 我发现我的构造函数开始看起来像这样: 不断增加的参数列表。由于“容器”是我的依赖项注入容器,所以为什么我不能这样做: 每堂课?不利之处是什么?如果执行此操作,则感觉就像我在使用精美的静态方法。请分享你对IoC和依赖注入疯狂的想法。 问题答案: 正确的是,如果将容器用作服务定位器,则它或多或少是光荣的静态工厂。由于种种原因,我认为这是一种反模式。 构造函数注入的奇妙好处之一是,它使违反单