将javamail会话传输保持打开是否可以接受?

时间:2010-12-02 10:41:11

标签: java javamail

我的应用程序需要临时发送电子邮件。我正在使用javamail的getDefaultSession和getTransport来发送消息,并且它都按预期工作。

但是我注意到发送可能需要很长时间 - 每次发送最多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)。

我最终必须在某种关闭钩子中关闭它。而且我可能必须有一个后备(如果连接丢失但传输没有实现)。但有没有理由不在应用程序生命周期内将其保持开放状态?

谢谢, 阿拉斯泰尔

2 个答案:

答案 0 :(得分:7)

我没有看到保持单个SMTP连接打开的任何问题,建议使用传输对象进行连接重用(请参阅JavaMail tutorial)。

此外,我建议您只在应用程序中打开一个smpt连接(通过Transport),将其保存在单个管理器实例中(即使用单例模式),避免最终保持不同连接打开的成本每个需要发送消息的组件。

答案 1 :(得分:4)

根据@Bill Shannon(JavaMail的作者)回答: Threadsafety in Javamail

  

由于传输表示与邮件服务器的连接,并且一次只有一个线程可以使用该连接,因此传输将同步来自多个线程的访问以保持线程安全,但您实际上只是想要从单个线程中使用它。

因此,如果您计划使用多线程中的单个Transport实例(现在通常就是这种情况),那么它实际上非常糟糕的主意性能的角度来看。您可能最好使用Transport开发某种ThreadLocal个实例池。