2014-03-06 56 views
0

我對我的新作品中的序列化字段,序列化對象中的對象感到困惑。
什麼應該被序列化或什麼應該被標記爲序列化的瞬態?Java:什麼時候序列化非序列化對象或將它們設置爲瞬態?

下面是一個例子:

@Stateless 
public class NonSerializedThingStateless{ 
... 
} 

@RequestScoped 
public class NonSerializedThingRequestScoped{ 
... 
} 


@Named 
@SessionScoped 
public class SerializedBean implements Serializable{ 
    @Inject 
    private NonSerializedThingRequestScoped nstrs; 

    @Inject 
    private NonSerializedThingStateless nsts; 

    private List<Something> list; //or something else like POJO 

    ... 
} 

是否有一個良好的,簡單的方法,我可以告訴我應該序列化注入或使用的類或指導?

這是真的嗎?我必須在序列化和將事物設置爲瞬態之間進行選擇,還是有其他方法?

回答

2

首先,警告一句話:您可能只想使用@Inject作爲簡單情況(通常是單身人士)。對於其他一切,自動裝配工作,但它可以非常快速地混淆。

這就是說,對於transient規則很簡單:當你閱讀對象(反序列化),你還有一切您需要重新創建原來的狀態?

如果一個對象依賴於當前的請求,答案可能是否定的:當從流中讀取bean時,請求將很快消失。

+0

@Inject幾乎可以在任何地方使用,單體在這個項目中很少見。那麼你對於請求作用域對象有什麼建議?現在一切正常,但我想提高程序的穩定性。我有一種感覺,我必須在序列化之間進行選擇,或者將它們設置爲暫時的,是否正確,還是我有更多的選擇? (我會改進這個問題) – CsBalazsHungary

+0

如果修改項目「修復」@Inject的用法需要幾周的時間,那可能已經太晚了。我的建議是針對新的項目,或者意識到某些使用「@Inject」的人是一個常見的問題來源。如果你不能或不需要改變它,那很好:-) –

+1

選項:'nstrs'必須是'transient'。也就是說,序列化是一個非常複雜的話題。獲取一個允許你模擬應用程序容器的框架。 Spring 3.2對模擬HTTP對象和編寫測試用例有很好的支持。然後編寫測試以確保序列化實際上符合您的期望。否則,它將成爲一個不斷的錯誤來源。 –

1

在Web應用程序中,經常會話範圍的變量將聲明爲implements Serializable。這有幾個常見的原因:

  1. 集羣環境(沒有運行Web應用程序不止一個應用服務器)可以配置爲會話複製。在這種情況下,當用戶會話發生變化時(例如,我將一個項目添加到購物車中),該更改將推送到羣集中的所有其他應用程序服務器。這些應用程序服務器運行在不同的JVM中,並需要將Java對象從一個JVM傳遞到另一個JVM的方式。爲此,他們將會話序列化成一串字節並將字節寫入套接字。
  2. 當單個應用程序服務器關閉時(可能會部署新的Web應用程序版本),它可以配置爲保留會話,這意味着它通常會將會話寫入磁盤。當它再次啓動時,將從磁盤讀取會話並在正在運行的Web應用程序中重新創建會話。再次執行此操作時,會話序列化爲byte[]並寫入文件系統。

在決定是否應該序列化一個字段或transient時,請考慮上述兩個示例。如果我們這樣做,那麼有一些簡單的規則。一般:

  1. 任何請求範圍應該作出transient。例如,用戶在搜索字段中鍵入的搜索文本。這些信息實際上並不需要保留,因爲它只與當前請求有關。
  2. 任何無狀態應該做transient。這裏的典型例子是一個記錄器。記錄器不需要序列化,因爲沒有應該保存的狀態。如果創建了新的記錄器,代碼將繼續運行得很好!
  3. 任何session-scoped應該被序列化。例如,用戶偏好或添加到購物車的項目。

因此,要回答你的問題:

是否有一個良好的,簡單的方法,我可以告訴我應該序列化注入或使用的類或指導?

想想會話序列化的原因(即我上面寫的是什麼),並確定序列化是否有意義,而不管字段是否被注入。

這是真的我必須在序列化和將事物轉換爲瞬態之間進行選擇,還是有其他方法?

如果您確定要序列化會話,那麼是的,你必須選擇什麼應該是序列化的,什麼應該是暫時的。 但是,如果您沒有在羣集環境中運行,在關機時沒有將會話保存到磁盤,並且沒有其他問題;那麼完全合理的做法是不要做任何事情Serializable,因爲不會發生序列化!