2010-12-02 60 views
13

我的應用程序需要臨時發送電子郵件。我使用javamail的getDefaultSession和getTransport來發送消息,並且它都按預期工作。將javamail會話傳輸打開是否可以接受?

但是我注意到發送可能需要很長時間 - 每發送最多7秒。如果我打破這些步驟,像這樣:

Transport transport = session.getTransport("smtp"); 
transport.connect(); 
transport.sendMessage(msg, addresses) 
transport.close(); 

......我可以看到,這是每次都需要幾乎所有時間的connect()調用。

我發現的所有例子都是這樣做的 - 獲取傳輸,連接,發送,斷開連接。但當然,它們都是一次性的例子,或者在一次通話中發送大批量的電子郵件。

我想我可能只是離開連接打開,就像這樣:

Transport transport = session.getTransport("smtp"); 
if (!transport.isConnected()) 
    transport.connect(); 
transport.sendMessage(msg, addresses) 

(有上的變化,在這裏:java mail keeping Transport object connected)。

我不得不在最後關閉它,在某種類型的關閉鉤子。而且我可能必須有一個回退(如果連接丟失,但傳輸不知道)。但是有什麼理由不在應用程序生命週期中像這樣打開它?

感謝, 阿拉斯泰爾

回答

7

我實在不明白在保持一個SMTP連接打開的任何問題,並建議用於連接複用(見JavaMail tutorial)使用傳輸對象。

此外,我建議您在應用程序中保持一個smpt連接(通過Transport),並將其保留在單個管理器實例中(即使用單例模式),從而避免保持打開不同連接的最終成本針對需要發送消息的每個組件。

+0

嗨托馬斯,謝謝你 - 正是我所希望的。我的確計劃在單例「EmailSender」實例中使用它,所以這應該沒問題。 – Alastair 2010-12-02 17:29:35

+0

這種方法可能會導致嚴重的多線程環境中的性能問題,如我的回答 – Yura 2016-03-23 21:33:25

2

@Bill Shannon的(JavaMail的作者)答案在這裏: Threadsafety in Javamail

由於運輸代表了一個郵件服務器的連接,並且只有一個線程可以使用在一次連接,傳輸將同步來自多個線程的訪問以維護線程安全,但是您真的只想從單個線程使用它。

所以,如果你打算從多個線程(這通常是這種情況現在)使用單Transport情況下,它實際上是從的觀點性能點又比較壞主意。使用ThreadLocal可能會更好地開發某種Transport實例池。

相關問題