我有一個使用PlayFramework 2.6.5和Guice DI(libraryDependencies += guice
)構建的Java web服務,正好是時間注入模式。所有依賴項通過構造函數注入,使用@Inject
和@ImplementedBy
,而Guice Module
爲空。`ProvisionException`被高速緩存,構造函數代碼永遠不會被重試
由於瞬態錯誤,一些依賴可以在構造函數中拋出異常。發生這種情況時,服務將失敗,並顯示ProvisionException
(這沒關係,客戶端需要重試)。
我發現這些異常被緩存,即使解決了異常的根本原因,Play或Guice都不會重試實例化這些類,並在Web服務重新啓動之前繼續拋出相同的異常。
例如,考慮下面的類Clock
,它的構造函數在午夜(00:xx)時失敗。只要系統時鐘到達午夜,服務就無法實例化該類。當時鍾達到凌晨1點時,相同的異常不斷被拋出。此外,異常消息總是相同(本例中的異常消息是第一時間發生異常的時間)
@ImplementedBy(OddClock.class)
public interface IClock {
//...
}
public class OddClock implements IClock {
@Inject
public OddClock() throws Exception {
if (DateTime.now().hourOfDay().get() == 0) {
throw new Exception(DateTime.now().toString());
}
}
}
public class TimeController {
@Inject
public TimeController(IClock clock) {
this.clock = clock;
}
}
順便說一句,相同的基本代碼還用於在控制檯應用程序,它沒有按」不會遇到這個問題,所以我認爲Play + Guice集成有一些特殊之處。任何建議關閉異常緩存?
這將工作。我不禁感到,重新設計'IClock'實現以避免在構造函數中引發異常會更加整潔。難道這種驗證不能懶惰地完成嗎? – Graham
我同意,如果有可能解決根本原因的異常,那麼這將是一個更好的方法。 –
感謝您的建議,我同意理想情況下可以改進代碼,但不幸的是,在真實情況下情況並非如此(上面的例子是說明問題的一個非常簡單的例子)。 @RichDougherty:_拋出異常並緩存異常看起來像Guice中的內置行爲。我仍然不明白爲什麼這個問題隻影響Web服務而不影響控制檯應用程序(請參閱我的最後一句),儘管,兩人都在使用Guice。 Play框架控制器是否被實例化爲單例? –