我的应用程序需要临时发送电子邮件。我正在使用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)。
我最终必须在某种关闭钩子中关闭它。而且我可能必须有一个后备(如果连接丢失但传输没有实现)。但有没有理由不在应用程序生命周期内将其保持开放状态?
谢谢, 阿拉斯泰尔
答案 0 :(得分:7)
我没有看到保持单个SMTP连接打开的任何问题,建议使用传输对象进行连接重用(请参阅JavaMail tutorial)。
此外,我建议您只在应用程序中打开一个smpt连接(通过Transport),将其保存在单个管理器实例中(即使用单例模式),避免最终保持不同连接打开的成本每个需要发送消息的组件。
答案 1 :(得分:4)
根据@Bill Shannon
(JavaMail的作者)回答:
Threadsafety in Javamail
由于传输表示与邮件服务器的连接,并且一次只有一个线程可以使用该连接,因此传输将同步来自多个线程的访问以保持线程安全,但您实际上只是想要从单个线程中使用它。
因此,如果您计划使用多线程中的单个Transport
实例(现在通常就是这种情况),那么它实际上非常糟糕的主意从性能的角度来看。您可能最好使用Transport
开发某种ThreadLocal
个实例池。