MimeMessage.saveChanges真的很慢
由于包含m.saveChanges()
,以下测试大约需要5秒钟才能执行。
import org.junit.Before; import org.junit.Test; import javax.mail.MessagingException; import javax.mail.Session; import javax.mail.internet.MimeMessage; import java.io.IOException; import java.util.Properties; import static org.junit.Assert.assertEquals; import static org.mockito.Mockito.mock; import static org.mockito.Mockito.when; @Test public void test1() throws MessagingException, IOException { Session s = Session.getDefaultInstance(new Properties()); MimeMessage m = new MimeMessage(s); m.setContent("Hello", "text/html; charset=utf-8"); m.saveChanges(); assertEquals(m.getContent(), "Hello"); assertEquals(m.getContentType(), "text/html; charset=utf-8"); }
我也用mockito嘲笑了Session,但它没有帮助:
Session s = mock(Session.class); when(s.getProperties()).thenReturn(new Properties());
这里有什么问题? 我可以嘲笑什么来加快速度?
修复人们在代码中首次使用JavaMail时最常犯的错误 。
DNS查找可能会损害某些计算机的性能。 对于JDK,您可以更改用于缓存DNS查找networkaddress.cache.ttl
和networkaddress.cache.negative.ttl
的安全属性,或者设置系统属性sun.net.inetaddr.ttl
和sun.net.inetaddr.negative.ttl
。 JDK 7及更高版本中的默认行为可以很好地缓存。
您最好使用会话属性来避免某些查找。
- 设置
mail.smtp.localhost
的会话属性以防止在HELO命令上进行名称查找。 - 设置
mail.from
或mail.host
(不是协议版本)的会话属性,因为这将阻止InternetAddress.getLocalAddress(Session)
上的名称查找。 调用MimeMessage.saveChanges()
,MimeMessage.updateHeaders()
,MimeMessage.updateMessageID()
或MimeMessage.setFrom()
将触发此方法。 - 设置
mail.smtp.from
会话属性以防止在EHLO命令上查找。 - 或者,如果您的代码依赖于
setFrom()
,则可以将系统属性mail.mime.address.usecanonicalhostname
设置为false
,但这应该由#2点处理。 - 对于IMAP,您可以尝试将
mail.imap.sasl.usecanonicalhostname
设置为false
,这是默认值。
由于您没有传输邮件,请通过将您的代码更改为以下内容来应用规则#2:
@Test public void test1() throws MessagingException, IOException { Properties props = new Properties(); props.put("mail.host", "localhost"); //Or use IP. Session s = Session.getInstance(props); MimeMessage m = new MimeMessage(s); m.setContent("Hello", "text/html; charset=utf-8"); m.saveChanges(); assertEquals(m.getContent(), "Hello"); assertEquals(m.getContentType(), "text/html; charset=utf-8"); }
如果要传输消息,请合并规则#1,#2和#3,这将阻止访问主机系统进行名称查找。 如果要在传输期间阻止所有DNS查找,则必须使用IP地址。