3

我對依賴注入感到困惑。我想要實現的是取代GlobalSettings.onStart()調用,其中我初始化了2.3中的一些靜態單例對象,並對這些對象進行了適當的依賴注入。Play Framework 2.4 - 依賴注入替換GlobalSettings.onStart()

我所試圖做的是這樣的:

控制器 - >模型(注入對象到這個模型)

我至今是半路措施;控制器:

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作爲PARAM:

private final SomeObject someObject; 

public SomeDataAjaxRequest(SomeObject someObject) { 
    super(null); 
    this.someObject = someObject; 
} 

在我build.sbt我:

routesGenerator := InjectedRoutesGenerator 

所以基本上我的問題是如何守ld我將SomeObject注入到我的模型中,還應該如何創建我的SomeObject對象,我認爲我不應該使用new SomeObject()

理想情況下,我想爲這些對象使用字段注入,因爲我不想混淆實際上可能具有相關參數的構造函數,而不是僅僅包含這些包含事物定義的實用類(SomeObject基本上只是加載一些來自數據庫的信息在整個應用程序的整個生命週期中都是靜態的,但可能會改變)。

也可能值得注意的是,我打算使用Guice來管理DI。

據我所知,我應該創建一個Guice DI工廠,並已經看到了這個文檔,但我仍然不確定如何將它集成到我的遊戲應用程序中。

回答

2

您不需要爲此明確創建一個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()); 
    } 
} 

請務必標註SomeObjectjavax.inject.Singleton,以確保其狀態。模塊中的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())); 
    } 
} 
+0

當我嘗試示例代碼在Play 2.4.2的這個答案的頂部,我得到了許多編譯器錯誤,比如「...模塊必須聲明爲抽象或實現configure()「。上面的代碼如何編譯?自從這篇文章發佈後,Play有了什麼變化?有什麼想法可以找到早期自我綁定的工作示例代碼? – devdanke

+0

我剛剛注意到導入和超類是錯誤的 - 我已經糾正了這個例子 –

+0

感謝您的反應如此之快我已經看到了一些早期的綁定例子,我認爲它們適用於Play 2.4.x.一些實現模塊,其他擴展AbstractModule。這兩種方法之間有什麼重要的區別嗎? – devdanke