Play Framework 2.6.X中使用Deadbolt,@this注入subjectPresent是否必须改造?
Play Framework 2.6.x + Deadbolt:模板注入操作的必要性解答
没错,你遇到的这个情况确实是必须执行的操作,这和Play 2.6之后的依赖注入(DI)升级,以及Deadbolt的设计逻辑直接挂钩。
为什么必须这么做?
- Play 2.6开始全面推进构造函数注入的最佳实践,原来的Twirl模板对象形式(靠静态
render方法调用)本质是依赖静态实例,完全不符合DI的设计思路。而类形式的模板正是Play为了适配DI容器专门设计的写法。 - Deadbolt的
subjectPresent这类模板助手本身是依赖注入的组件——它需要从DI容器中获取DeadboltHandler等核心服务才能正常工作。所以必须通过@this语法把它注入到模板里,而这就要求模板必须是类(对象根本没法接收构造函数注入的依赖)。
正确的操作步骤
把Twirl模板改成类形式
原来的对象模板写法:@() <!-- 你的模板内容 -->改成带
@this注入的类模板:@this(subjectPresent: be.objectify.deadbolt.scala.views.html.subjectPresent) @() <!-- 使用subjectPresent的示例 --> @subjectPresent() { <p>当前用户已完成登录验证</p> }控制器中注入模板并调用
原来靠静态render的控制器写法:class MyController extends Controller { def index = Action { Ok(views.html.index.render()) } }改成构造函数注入模板的写法:
import play.api.mvc._ import javax.inject.Inject class MyController @Inject()(indexView: views.html.index, val controllerComponents: ControllerComponents) extends BaseController { def index = Action { Ok(indexView()) } }
有没有绕过的办法?
说实话,不建议尝试绕过——Play 2.6之后官方已经逐步弱化静态模板的支持,而且Deadbolt的模板助手完全依赖DI容器提供的服务,强行用对象模板的话,运行时大概率会抛出空指针或者依赖缺失的异常,反而给自己找麻烦。
内容的提问来源于stack exchange,提问作者bharal
相关产品推荐
相关产品推荐

