2017-06-08 145 views
1

由於列入了m.saveChanges(),下面的測試需要大約5秒的時間來執行。MimeMessage.saveChanges真的很慢

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("<b>Hello</b>", "text/html; charset=utf-8"); 
    m.saveChanges(); 
    assertEquals(m.getContent(), "<b>Hello</b>"); 
    assertEquals(m.getContentType(), "text/html; charset=utf-8"); 
} 

我還嘲笑與在的Mockito會話,但它並不能幫助:

Session s = mock(Session.class); 
when(s.getProperties()).thenReturn(new Properties()); 

這裏有什麼問題嗎?我可以模擬什麼來加快速度?

回答

4

首先在您的代碼中修復most common mistakes people make when using JavaMail

DNS lookup可能會損害某些機器的性能。對於JDK,您可以更改緩存DNS查找的安全屬性networkaddress.cache.ttl and networkaddress.cache.negative.ttl或設置系統屬性sun.net.inetaddr.ttl and sun.net.inetaddr.negative.ttl。 JDK 7和更高版本中的默認行爲在緩存方面做得很好。

最好,您可以使用會話屬性來避免一些這些查找。

  1. 將會話屬性設置爲mail.smtp.localhost以防止在HELO命令上進行名稱查找。
  2. 設置會話屬性爲mail.from or mail.host(不是協議版本),因爲這將阻止名稱查找InternetAddress.getLocalAddress(Session)。調用MimeMessage.saveChanges()MimeMessage.updateHeaders(),MimeMessage.updateMessageID()MimeMessage.setFrom()將觸發此方法。
  3. 設置會話屬性爲mail.smtp.from以防止在EHLO命令上查找。
  4. 或者,如果您的代碼依賴setFrom(),則可以將系統屬性mail.mime.address.usecanonicalhostname設置爲false,但這應該由點#2處理。
  5. 對於IMAP,您可以嘗試將mail.imap.sasl.usecanonicalhostname設置爲false,這是默認值。

    @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("<b>Hello</b>", "text/html; charset=utf-8"); 
        m.saveChanges(); 
        assertEquals(m.getContent(), "<b>Hello</b>"); 
        assertEquals(m.getContentType(), "text/html; charset=utf-8"); 
    } 
    

    如果你要傳送的消息再結合規則#1,#2,#3:

由於您沒有運送的消息,通過改變你的代碼的應用規則#2這將阻止訪問主機系統進行名稱查找。如果您想在傳輸過程中阻止所有DNS查找,那麼您必須使用IP地址。