Play Framework 2.4 - 依赖注入来替换 GlobalSettings.onStart()
Play Framework 2.4 - Dependency injection to replace GlobalSettings.onStart()
我对依赖注入感到困惑。我想要实现的是替换 GlobalSettings.onStart()
调用,我在 2.3 中初始化了一些静态单例对象,并对这些对象进行了适当的依赖注入。
我想做的是:
Controller -> Model(将一个对象注入到这个模型中)
到目前为止,我所采取的是一种折衷措施;在控制器中:
private static SomeObject myStaticSingletonObject = new SomeObject();
public Promise<Result> getSomeData() {
return handleRequest(() -> new SomeDataAjaxRequest(myStaticSingletonObject));
}
public Promise<Result> handleRequest(Function0<AbstractAjaxRequest<?>> supplier) {
Promise<AbstractAjaxRequest<?>> promise = Promise.promise(supplier);
return promise.map(arg -> ok(arg.getResponse()));
}
handleRequest() 是我使用的自定义方法,并没有真正相关,但为了完整起见,我将其包括在内:
在模型中,我只将 SomeObject 作为参数:
private final SomeObject someObject;
public SomeDataAjaxRequest(SomeObject someObject) {
super(null);
this.someObject = someObject;
}
在我的 build.sbt 我有:
routesGenerator := InjectedRoutesGenerator
所以基本上我的问题是我应该如何将 SomeObject 注入我的模型以及我应该如何创建我的 SomeObject 对象,我认为我不应该使用 new SomeObject()
.
理想情况下,我想对这些对象使用字段注入,因为我不想弄乱可能实际上具有模型相关参数的构造函数,而不仅仅是这些包含事物定义的实用程序 类 (SomeObject 基本上只是从数据库中加载一些信息,这些信息目前在应用程序的整个生命周期中都是静态的,但可能会改变)。
另外可能值得注意的是,我打算使用 Guice 来管理 DI。
我知道我应该创建一个 Guice DI 工厂并且已经看过相关的文档,但我仍然不确定如何将它集成到我的 play 应用程序中。
您不需要为此显式创建 Guice DI 工厂。
相反,创建一个模块并使用它来配置任何绑定,并且 - 对您来说很重要 - 替换 onStart()
。
import play.api.inject.Module;
public class SomeModule extends Module {
@Override
public Seq<Binding<?>> bindings(final Environment environment,
final Configuration configuration)
{
return seq(bind(SomeObject.class).toSelf().eagerly());
}
}
确保用 javax.inject.Singleton
注释 SomeObject
以确保其状态。模块中 eagerly
的要点是确保对象尽早初始化。
SomeObject
将可用于 DI,已被调用一次;您可以使用构造函数来初始化您需要做的任何事情。
要向您的应用程序公开此模块,请将其添加到 application.conf
:
play {
modules {
enabled += "com.example.SomeModule"
}
}
在您的控制器中,只需像往常一样注入实例:
public class SomeController extends Controller {
private final SomeObject someObject;
@Inject
public SomeController(final SomeObject someObject) {
this.someObject = someObject;
}
public Promise<Result> getSomeData() {
return handleRequest(() -> new SomeDataAjaxRequest(someObject));
}
public Promise<Result> handleRequest(Function0<AbstractAjaxRequest<?>> supplier) {
return Promise.promise(supplier)
.map(arg -> ok(arg.getResponse()));
}
}
我对依赖注入感到困惑。我想要实现的是替换 GlobalSettings.onStart()
调用,我在 2.3 中初始化了一些静态单例对象,并对这些对象进行了适当的依赖注入。
我想做的是:
Controller -> Model(将一个对象注入到这个模型中)
到目前为止,我所采取的是一种折衷措施;在控制器中:
private static SomeObject myStaticSingletonObject = new SomeObject();
public Promise<Result> getSomeData() {
return handleRequest(() -> new SomeDataAjaxRequest(myStaticSingletonObject));
}
public Promise<Result> handleRequest(Function0<AbstractAjaxRequest<?>> supplier) {
Promise<AbstractAjaxRequest<?>> promise = Promise.promise(supplier);
return promise.map(arg -> ok(arg.getResponse()));
}
handleRequest() 是我使用的自定义方法,并没有真正相关,但为了完整起见,我将其包括在内:
在模型中,我只将 SomeObject 作为参数:
private final SomeObject someObject;
public SomeDataAjaxRequest(SomeObject someObject) {
super(null);
this.someObject = someObject;
}
在我的 build.sbt 我有:
routesGenerator := InjectedRoutesGenerator
所以基本上我的问题是我应该如何将 SomeObject 注入我的模型以及我应该如何创建我的 SomeObject 对象,我认为我不应该使用 new SomeObject()
.
理想情况下,我想对这些对象使用字段注入,因为我不想弄乱可能实际上具有模型相关参数的构造函数,而不仅仅是这些包含事物定义的实用程序 类 (SomeObject 基本上只是从数据库中加载一些信息,这些信息目前在应用程序的整个生命周期中都是静态的,但可能会改变)。
另外可能值得注意的是,我打算使用 Guice 来管理 DI。
我知道我应该创建一个 Guice DI 工厂并且已经看过相关的文档,但我仍然不确定如何将它集成到我的 play 应用程序中。
您不需要为此显式创建 Guice DI 工厂。
相反,创建一个模块并使用它来配置任何绑定,并且 - 对您来说很重要 - 替换 onStart()
。
import play.api.inject.Module;
public class SomeModule extends Module {
@Override
public Seq<Binding<?>> bindings(final Environment environment,
final Configuration configuration)
{
return seq(bind(SomeObject.class).toSelf().eagerly());
}
}
确保用 javax.inject.Singleton
注释 SomeObject
以确保其状态。模块中 eagerly
的要点是确保对象尽早初始化。
SomeObject
将可用于 DI,已被调用一次;您可以使用构造函数来初始化您需要做的任何事情。
要向您的应用程序公开此模块,请将其添加到 application.conf
:
play {
modules {
enabled += "com.example.SomeModule"
}
}
在您的控制器中,只需像往常一样注入实例:
public class SomeController extends Controller {
private final SomeObject someObject;
@Inject
public SomeController(final SomeObject someObject) {
this.someObject = someObject;
}
public Promise<Result> getSomeData() {
return handleRequest(() -> new SomeDataAjaxRequest(someObject));
}
public Promise<Result> handleRequest(Function0<AbstractAjaxRequest<?>> supplier) {
return Promise.promise(supplier)
.map(arg -> ok(arg.getResponse()));
}
}