Can Akka Typed be integrated with Spring Boot?

Previously I can integrate classic Akka with Spring Boot by following the article: https://www.baeldung.com/akka-with-spring, which brings the two best worlds together.
With Akka Typed, how can I achieve the similar integration with Spring Boot? Can someone point me to an example.
Thanks in advance!

1 Like

I’m just venturing a guess that it can be done, but it just hasn’t yet. I’ve started to play around with the idea but I’m still in the early stages. I am very interested in Akka Typed/Spring Boot integration as well.

You can probably learn from what has been done in Play. It’s using Guice but I guess it’s similar to Spring DI.
https://www.playframework.com/documentation/2.8.x/AkkaTyped

Here’s how we integrate Spring Boot with Akka Typed:

@Configuration
public class ServiceConfig {

    @Autowired
    private Environment environment;

    @Bean
    public Scheduler systemScheduler() {
        return system().scheduler();
    }

    @Bean
    public Config akkaConfig() {
        return ConfigFactory.load();
    }

    @Bean(destroyMethod = "terminate")
    public ActorSystem<SpawnProtocol.Command> system() {
        Config config = akkaConfig();
        return ActorSystem.create(
                Behaviors.setup(ctx -> {
                    akka.actor.ActorSystem unTypedSystem = Adapter.toClassic(ctx.getSystem());
                    AkkaManagement.get(unTypedSystem).start();
                    ClusterBootstrap.get(unTypedSystem).start();
                    return SpawnProtocol.create();
                }), config.getString("some.cluster.name"));
    }

    @Bean
    public ClusterSharding clusterSharding() {
        return ClusterSharding.get(system());
    }

    @Bean
    public ActorRef<ShardingEnvelope<Command>> someShardRegion() {
        ClusterShardingSettings settings = ClusterShardingSettings
                .create(system())
                ...

        return clusterSharding().init(Entity.of(...));
    }

...
}

Then inject in a service


@Service
public class SomeService {

    public static final Duration TIMEOUT = Duration.ofSeconds(10);
    private final ActorRef<ShardingEnvelope<Command>> subscriptionShardRegion;
    private final Scheduler scheduler;

    @Autowired
    public SomeService(
            ActorRef<ShardingEnvelope<Command>> someShardRegion,
            Scheduler scheduler
    ) {
        this.someShardRegion = someShardRegion;
        this.scheduler = scheduler;
    }

    public void someFireForgetMethod(){
        ...
        someShardRegion.tell(new ShardingEnvelope<>(entityId, command));
        ...
    }

    public Mono<ResponseType> someNeedResponseMethod(){
        CompletionStage<ResponseType> willBeResponse = AskPattern.ask(
            someShardRegion, 
            replyTo -> new ShardingEnvelope<>(entityId, new Command(replyTo)),
            TIMEOUT,
            scheduler
        );
        return Mono.fromCompletionStage(willBeResponse);
    }
}