应引入无Scala后缀的akka-actor-typed(需显式指定type=jar),配置必须使用ConfigFactory.defaultReference()或合并自定义配置,Behavior必须返回非null行为,测试须用akka-testkit-typed-junit5及proper cleanup。

怎么在 Maven 项目里正确引入 Akka Actor 2.6+(Java)
Akka 2.6 起彻底移除了对 Scala 2.11/2.12 的支持,且 Java API 不再是“附属”,但默认依赖仍带 Scala 运行时——直接加 akka-actor-typed_2.13 会导致 Java 项目多出一堆无关的 scala-library 和隐式类路径冲突。
实操建议:
- 用
akka-actor-typed(无下划线和 Scala 版本后缀)这个纯 Java 模块,它不拉 Scala 依赖 - Maven 坐标必须指定
<type>jar</type>,否则 Maven 可能误取到 pom-only artifact - 显式排除
akka-actor(旧 untyped)避免版本混用,哪怕你暂时不用 typed 模型
<dependency> <groupId>com.typesafe.akka</groupId> <artifactId>akka-actor-typed</artifactId> <version>2.8.5</version> <type>jar</type> </dependency>
启动 ActorSystem 时为什么报 “No configuration setting found for key 'akka.actor.provider'”
这是 Akka 2.6+ 的硬性要求:不再接受空配置。哪怕只跑一个本地 actor,也必须提供基础配置,否则 ActorSystem.create() 直接抛 ConfigException。
常见错误现象:
立即学习“Java免费学习笔记(深入)”;
- 只传名字如
ActorSystem.create("my-system")→ 报错 - 用
ConfigFactory.empty()→ 同样报错,empty 不等于 default
实操建议:
- 最简解法:用
ConfigFactory.defaultReference(),它加载reference.conf中的全部默认值 - 若需自定义,用
ConfigFactory.parseString("akka.actor.provider = local")合并到 defaultReference 上,别覆盖 - Java 代码里别手写 HOCON 字符串拼接,容易漏引号或换行——优先用
ConfigFactory.parseResources("application.conf")
写第一个 HelloActor 时,Behavior<String> 怎么响应消息又不卡死
Akka Typed 的核心是不可变行为链,onMessage 返回新 Behavior 才算处理完成;如果忘了 return 或返回了 Behaviors.same() 却没做状态更新,actor 就会静默丢弃后续消息。
使用场景:
- 简单状态机(比如连接/断开/重试)适合用
Behaviors.setup()+ 闭包捕获变量 - 需要持久化或跨 actor 共享状态?别在 Behavior 里存字段——那是反模式,该用
EventSourcedBehavior或外部存储
简短示例(修正版):
Behavior<String> helloBehavior = Behaviors.receive((ctx, msg) -> {
ctx.getLog().info("Received: {}", msg);
// 必须返回一个 Behavior,不能 void,不能 null
return Behaviors.same(); // 或 Behaviors.stopped()
});
JUnit 5 测试 Actor 时,TestKit 报 “ActorSystem is terminated”
Akka 2.6+ 废弃了旧 TestKit,Java 用户应改用 akka-testkit-typed-junit5,但直接 new TestKit 仍会触发已废弃路径,导致系统提前关闭。
性能与兼容性影响:
- 旧
TestKit强制同步执行,掩盖调度问题;新TestProbe默认异步,更贴近真实行为 - 测试中调用
system.terminate()是必须的,但得等它真正完成——否则 next test 会复用已关系统
实操建议:
- 用
TestProbe<String> probe = testKit.createTestProbe()替代手动构造 actor - 发送消息后,用
probe.receiveMessage()阻塞等待,别用Thread.sleep() - @AfterEach 里写
system.terminate().toCompletableFuture().join(),确保清理干净
Behavior 构造必须返回非 null 行为,哪怕只是 Behaviors.empty(),否则 actor 一收消息就静默死亡。










