在Play Framework中使用Tapir Router时移除JSR330依赖实现单例
在Play Framework中实现Tapir Router单例(移除JSR330依赖)
下面提供三种无需JSR330依赖的实现方案,确保Router以单例运行:
方案1:Play原生依赖注入绑定单例
利用Play自带的Guice集成实现单例绑定,无需额外库:
- 移除
ApiRouter类上的@Singleton注解 - 创建自定义模块类,在其中绑定
ApiRouter为饿汉式单例:
import com.google.inject.AbstractModule import play.api.inject.Module class ApiModule extends AbstractModule with Module { override def configure(): Unit = { // asEagerSingleton确保启动时初始化实例,避免重复创建 bind(classOf[ApiRouter]).asEagerSingleton() } }
- 在
conf/application.conf中注册该模块:
play.modules.enabled += "com.yourpackage.ApiModule"
方案2:手动实现Scala单例模式
方式A:直接使用Scala对象
将ApiRouter改为Scala对象(本身就是JVM级单例):
import sttp.tapir.server.play.PlayServerInterpreter import play.api.mvc.Router object ApiRouter { // 初始化Tapir端点并生成路由 val router: Router = PlayServerInterpreter().toRoutes(/* 你的Tapir端点集合 */) }
在conf/routes中直接引用:
-> /api ApiRouter.router
注意:若Router依赖其他组件,需确保依赖也是单例或已提前初始化。
方式B:懒加载单例类
若需要保留类的结构(比如有构造参数),可实现懒加载单例:
class ApiRouter(yourDependency: YourDependency) { val router: Router = PlayServerInterpreter().toRoutes(/* 端点集合 */) } object ApiRouter { private lazy val instance: ApiRouter = new ApiRouter(/* 初始化单例依赖 */) def getInstance: ApiRouter = instance }
后续通过ApiRouter.getInstance获取单例实例即可。
方案3:直接绑定单例端点路由
跳过单独的Router类,直接在单例对象中定义并生成Tapir路由:
import sttp.tapir._ import sttp.tapir.server.play.PlayServerInterpreter import play.api.mvc._ import scala.concurrent.Future object ApiEndpoints { // 定义端点 private val helloEndpoint = endpoint.get.in("hello").out(stringBody) // 生成单例路由 val helloRoute: Handler = PlayServerInterpreter().toRoute(helloEndpoint) { _ => Future.successful(Right("Hello from Tapir!")) } }
在conf/routes中绑定:
-> /api ApiEndpoints.helloRoute
内容的提问来源于stack exchange,提问作者zella
相关产品推荐
相关产品推荐

