Допустимо ли оставить сеанс javamail Transport открытым?
Мое приложение должно отправлять электронную почту на разовой основе. Я использую javamail getDefaultSession и getTransport для отправки сообщения, и все работает как ожидалось.
Однако я заметил, что отправка может занять много времени - до семи секунд за отправку. Если я сломаю шаги, вот так:
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 storage Транспортный объект подключен).
Мне придется закрыть его в конце концов, в каком-то закрытии. И мне может потребоваться резервное копирование (если соединение было потеряно, но транспорт не понял). Но есть ли причина не просто оставить его открытым, как это во время срока службы приложения?
Спасибо,
Аластер
Ответы
Ответ 1
Я не вижу никакой проблемы в том, чтобы открыть одно SMTP-соединение, и рекомендуется использовать объект транспорта для повторного использования соединения (см. учебное пособие по JavaMail).
Кроме того, я бы рекомендовал вам сохранить только одно smpt-соединение (через Transport), открытое в вашем приложении, сохраняя его в одном экземпляре менеджера (например, используя шаблон singleton), избегая возможной стоимости сохранения другого соединения для каждый компонент, которому необходимо отправить сообщение.
Ответ 2
В соответствии с @Bill Shannon
(автор JavaMail) ответьте здесь:
Threadsafety в Javamail
Поскольку Transport представляет соединение с почтовым сервером, и только один поток может использовать соединение за раз, Transport будет синхронизировать доступ из нескольких потоков для обеспечения безопасности потоков, но вы действительно хотите использовать его только из одного потока.
Итак, если вы планируете использовать один экземпляр Transport
из нескольких потоков (что обычно имеет место в настоящее время), это на самом деле довольно плохая идея от точка зрения. Вероятно, вам лучше создать какой-то пул экземпляров Transport
, используя ThreadLocal
.