2016-11-16 77 views
3

我剛剛開始,我不認爲我很瞭解它。從我所瞭解的所有控制器在創建路由器的那一刻起就被創建爲依賴關係。然後,他們繼續活動,直到應用程序終止時路由器死亡。如果是這種情況,將他們宣佈爲單身人士似乎是多餘的。爲什麼在播放2.5中使用單聲道控制器?

+0

你不必聲明他們是單身人士。你從哪裏讀到的? – Nio

+0

無處。但是如果你看看播放裝置附帶的控制器,它們都被標註爲Singeltons – user25470

+0

啊我看到了,我在下面放了一個更大的評論 - 它是關於無國籍的。 – Nio

回答

3

爲了擺脫全局狀態(這違背了無狀態的設計思路)發揮引進DI(我覺得周圍V2.4)和V2.5它現在使用的注射路由器默認。 Google Guice是由Play打包的默認DI框架(您可以使用其他框架,但Guice是默認設置)。現在(一般情況下)Guice認爲創建Controller的新實例比使用Singleton更快,並且更安全線程 - 請參閱Guice docs for more

如果您將have a need限制爲只有1個控制器的實例,那麼您可以將其標記爲單例,但您必須將其設置爲Thread-safe,因爲它將在線程之間共享。

我認爲Activator模板可以用更多的文檔來解決它們爲什麼看起來會生成@Singleton控制器,因爲它們似乎並不需要,因爲它很混亂。例如HomeController(在Play-Scala種子中)例如當它沒有展示任何情況時被混淆地宣佈爲@Singleton

一般來說,最好不要使用@Singleton,除非您對不變性和線程安全性有公正的理解。如果你認爲你有一個Singleton的用例,只要確保你保護了任何共享狀態。

簡而言之,請勿使用@Singleton

+0

所以最好的做法是將每個控制器聲明爲@Singleton? –

+0

我想我還是有點困惑。我仍然能夠看到更多的一個實例將被創建的時間。所以單身符號似乎仍然是多餘的。此外,我的印象是,所有請求都由同一個線程處理,所以無論它是無狀態還是不是無關緊要 – user25470

+0

@ user25470每個請求1個線程,否則所有請求都必須排隊等待其開啓1這意味着你的應用程序非常緩慢。您可能已經閱讀過文檔中的操作意圖是非阻塞的 - 這意味着您不應該在控制器操作中做任何可能導致其切換上下文(例如,I/O)的事情 - 這是因爲默認Play的線程池是主機上每個核心的1個線程。所以一個線程被分配一個請求,快速執行這個動作(非阻塞),然後迅速返回到緩衝池來處理下一個請求。 – Nio

1

如果你有一個由路由器實例化的控制器(即默認值),那麼它們是隱含的單例,因爲路由器只存在一次。但是,如果您將控制器注入其他地方,除非將其標記爲單例,否則您仍會獲得新實例。

來源:https://github.com/playframework/playframework/issues/4508#issuecomment-127820190

+0

您能否給我一個何時在別處注入控制器的例子? – user25470

+0

不,我認爲那是不好的做法。如果你想共享功能,你應該創建一個商業服務或其他輔助類。我認爲關於在其他地方注入控制器的觀點相當技術化,以至於控制器不是真正的單身。 – rethab

+0

這非常有幫助。謝謝。 – iraxef

相關問題