Spring 高效批量邮件发送 - shupili141005 - ITeye技术网站
Gmail 邮件发送配置
email.properties 文件:
# Gmail Configuration
email.host=smtp.gmail.com
email.port=587
email.username=******
email.password=******
email.defaultEncoding=UTF-8
applicationContext.xml 文件:
<!-- Email Service -->
<bean id="mailSender" class="org.springframework.mail.javamail.JavaMailSenderImpl">
<property name="host" value="${email.host}"/>
<property name="port" value="${email.port}"/>
<property name="username" value="${email.username}"/>
<property name="password" value="${email.password}"/>
<property name="javaMailProperties">
<props>
<prop key="mail.transport.protocol">smtp</prop>
<prop key="mail.smtp.starttls.enable">true</prop>
<prop key="mail.smtp.host">smtp.gmail.com</prop>
<prop key="mail.smtp.auth">true</prop>
<prop key="mail.smtp.port">465 </prop>
</props>
<!--
<value>
mail.smtp.auth=true
</value>
-->
</property>
<property name="defaultEncoding" value="${email.defaultEncoding}"></property>
</bean>
<bean id="emailSender" class="com.tucue.common.util.SimpleEmailSender">
<property name="mailSender" ref="mailSender"></property>
</bean>
<!-- end of Email Service -->
FAQ :
com .sun .mail .smtp .SMTPSendFailedException: 530 5 .7 . 0 Must issue a STARTTLS command first .
A :
<prop key="mail.smtp.starttls.enable">true</prop>
Send Batch Mail
http://static.springsource.org/spring/docs/2.5.x/api/org/springframework/mail/MailSender .html
Method Summary
void |
send (SimpleMailMessage simpleMessage) Send the given simple mail message. |
void |
send (SimpleMailMessage [] simpleMessages) Send the given array of simple mail messages in batch. |
Method Summary
MimeMessage |
createMimeMessage () Create a new JavaMail MimeMessage for the underlying JavaMail Session of this sender. |
MimeMessage |
createMimeMessage (InputStream contentStream) Create a new JavaMail MimeMessage for the underlying JavaMail Session of this sender, using the given input stream as the message source. |
void |
send (MimeMessage mimeMessage) Send the given JavaMail MIME message . |
void |
send (MimeMessage [] mimeMessages) Send the given array of JavaMail MIME messages in batch . |
void |
send (MimeMessagePreparator mimeMessagePreparator) Send the JavaMail MIME message prepared by the given MimeMessagePreparator. |
void |
send (MimeMessagePreparator [] mimeMessagePreparators) Send the JavaMail MIME messages prepared by the given MimeMessagePreparators. |
方案一:首先获取要发送邮件的所有地址,然后迭代的封装单个 MimeMessage 之后就将其发送出去(即发送一封邮件)。
SimpleEmailSender.java 文件
- /**
- * 功能: 传入邮件接收者地址、标题和内容,然后发送单个邮件服务
- * @param {@link String} emailAddress
- * @param {@link String} subject
- * @param {@link String} content
- * @throws MessagingException
- */
- public static void sendSimpleEmail(<span style="color: #ff0000;">String receiver</span>
- , String subject, String content) throws MessagingException {
- JavaMailSender sender = (JavaMailSender) mailSender;
- <span style="color: #ff0000;">MimeMessage mimeMessage</span>
- = sender.createMimeMessage();
- MimeMessageHelper messageHelper = new MimeMessageHelper(mimeMessage, true, "UTF-8");
- messageHelper.setFrom("***@<span style="color: #ff0000;">gmail</span>
- .com");
- messageHelper.setTo(receiver);
- messageHelper.setSubject(subject);
- messageHelper.setText(content, true);
- sender.send(<span style="color: #ff0000;">mimeMessage</span>
- );
- }
UserInfoAction.java 文件
- // 用户 -> 批量邮件发送
- public String sendBatchEmail() {
- if(!emailReceiverList.equals("")) { // 发送用户邮件
- // String[] receiverList = emailReceiverList.split(",");
- String[] receiverList = new String[20];
- for(int i = 0; i < 20; ++i) {
- receiverList[i] = "[email protected]";
- }
- long start = System.currentTimeMillis();
- for(<span style="color: #ff0000;">String receiver: receiverList</span>
- ) {
- try {
- <span style="color: #ff0000;">SimpleEmailSender.sendSimpleEmail(receiver, emailSubject, emailContent);</span>
- } catch (MessagingException e) {
- e.printStackTrace();
- }
- }
- long end = System.currentTimeMillis();
- System.out.println(end - start);
- } else {// 发送用户组邮件
- List<String> receiverList = userInfoService.getUserEmailByGroupId(groupID);
- for(String receiver: receiverList) {
- try {
- SimpleEmailSender.sendSimpleEmail(receiver, emailSubject, emailContent);
- } catch (MessagingException e) {
- e.printStackTrace();
- }
- }
- }
- return SUCCESS;
- }
方案二:首先获取要发送邮件的所有地址,然后一起封装成 MimeMessage[] 之后就将其发送出去(即批量发送所有要发送的邮件)。
SimpleEmailSender.java 文件
- /**
- * 功能: 传入邮件接收者地址列表、标题和内容,然后发送批量邮件服务
- * @param {@link List<String>} receiverList
- * @param {@link String} subject
- * @param {@link String} content
- * @throws MessagingException
- */
- public static void sendBulkEmail(<span style="color: #ff0000;">List<String> receiverList</span>
- , String subject, String content) throws MessagingException {
- JavaMailSender sender = (JavaMailSender) mailSender;
- int len = receiverList.size();
- <span style="color: #ff0000;">MimeMessage[] mimeMessageList</span>
- = new MimeMessage[len]; // 注意:是<span style="color: #ff0000;">数组类型</span>
- MimeMessageHelper messageHelper = null;
- for(int i = 0; i < len; ++i) {
- <span style="color: #ff0000;">mimeMessageList[i]</span>
- = sender.createMimeMessage();
- messageHelper = new MimeMessageHelper(mimeMessageList[i], true, "UTF-8");
- messageHelper.setFrom("[email protected]");
- messageHelper.setTo(receiverList.get(i));
- messageHelper.setSubject(subject);
- messageHelper.setText(content, true);
- }
- sender.send(<span style="color: #ff0000;">mimeMessageList</span>
- );
- }
UserInfoAction.java 文件
- // 用户 -> 批量邮件发送
- public String sendBatchEmail() {
- if(!emailReceiverList.equals("")) { // 发送用户邮件
- / String[] receiverList = emailReceiverList.split(",");
- <span style="color: #ff0000;">List<String> receiverList</span>
- = new ArrayList<String>(20);
- for(int i = 0; i < 20; ++i) {
- receiverList.add("[email protected]");
- }
- long start = System.currentTimeMillis();
- try {
- / SimpleEmailSender.sendBulkEmail(Arrays.asList(receiverList), emailSubject, emailContent);
- SimpleEmailSender.<span style="color: #ff0000;">sendBulkEmail(receiverList</span>
- emailSubject, emailContent);
- } catch (MessagingException e) {
- e.printStackTrace();
- }
- long end = System.currentTimeMillis();
- System.out.println(end - start);
- } else {// 发送用户组邮件
- List<String> receiverList = userInfoService.getUserEmailByGroupId(groupID);
- try {
- SimpleEmailSender.sendBulkEmail(receiverList, emailSubject, emailContent);
- } catch (MessagingException e) {
- e.printStackTrace();
- }
- }
- return SUCCESS;
- }
根据上述两种方案,通过发送 20 封邮件进行测试后发,发现第二种方案(用时 36984 ms)比第一种(81266 ms)的 执行效率 2.1 倍多 。
总结
通过这次实验,感觉自己收获了不少。第一,评价哪种方案优劣,用你需要的数据测试就能体现执行效率,但健壮性和可扩展性就不能一概而论了;第二,要想编写更加高效的代码,就必须对你特别重要(特别是常用基础类)的 API 有足够的熟知。就以这个案例为例,刚开始我没有仔细看过 JavaMailSender 的 API ,导致就不知道用 send (MimeMessage [] mimeMessages) 这个函数,所以也不知道存在第二种方案。后来突然发现有这个函数,就像能不能对先前的发送单个邮件服务加以改进,第二种方案也就是这样萌生的。