2017-01-23 32 views
7

當開發人員將可變性引入Spring組件時,我們遇到了多線程問題。這樣的事情:確保彈簧組件是無狀態的

@Component //singleton 
public class MyComponent { 
... 
private String intermediateResults; 
public String businessMethod() { 
... fills in intermediateResults; 
} 

public String thisGetterShouldNotBeHere() { 
    return intermediateResults; 
} 
} 

這導致與多線程錯誤 - 字段intermediateResults已被訪問從不同的線程。

是否有一種方法可以防止向Spring Singleton添加狀態,例如通過某種靜態分析儀? SonarQube插件? Eclipse插件? 感謝您的建議。

+0

http://stackoverflow.com/questions/777849/proper-usage-of-synchronized-singleton – joc

+0

只是一個問題:是不是'businessMethod()'使類可變,而不是Getter? –

+0

肯定businessMethod使它變化。 – leokom

回答

2

谷歌的MutabilityDetector似乎能夠做的正是你需要的東西:

可變性探測器是用來分析Java類和給定類的實例是否是不可變的報告。它可以使用:

  • 在單元測試中,使用assertImmutable(MyClass.class)之類的斷言。你的課程實際上是不可變的嗎?那剛剛做出的改變之後怎麼樣?
  • 作爲FindBugs插件。你用@Immutable註解的那些類是他們實際上? 在運行時。你的API是否需要被賦予不可變對象? 從命令行。你想在整個代碼庫中快速運行Mutability Detector嗎?

我想反正建議增加一個明確的合同,指出類應該要麼通過javadoc或通過@Immutable註釋類本身是不可變的,允許(懂事)開發者維護類必需品。 (如果谷歌的探測器未能檢測到特定類型的不變性,例如:Are String, Date really immutable?

+1

似乎是一個不錯的工具。將嘗試 – Andres

+0

@Andres它確實,嘗試驗證從構造函數接受集合並使用Collection.unmodifiableCollection(...)設置其最終狀態的類。你會驚訝的結果:) – snovelli

+1

這是一個偉大的工具,非常感謝你,@snovelli! – leokom

1

您可以實現與任何靜態分析自己的規則(比如FindBugs的,PMD和Checkstyle的)來檢查您的類:

  • 只允許最終性能
  • 延伸的給定類
  • 是最後
  • 用途構造依賴注入

不過,據我所知,沒有工具特異性爲此設置了開箱即用。

或者,您可以創建一個@Immutable註釋並在其中執行檢查。

+0

許多Spring應用程序通過setter來使用依賴注入。在這種情況下,「final」不是一種選擇。不確定自動裝配最終字段 - 你有任何經驗嗎? –

+3

如果您想確保不變性,您必須使用構造函數依賴注入 – Andres

+0

使用構造函數依賴注入。不僅解決了這種情況,而且具有幾個優點。請參閱:https://spring.io/blog/2007/07/11/setter-injection-versus-constructor-injection-and-the-use-of-required/ – borjab