Spring 高效批量邮件发送
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" 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" ref="mailSender"></property>
?? ?</bean>
?? ?<!-- end of Email Service -->
?
FAQ:
/** * 功能: 传入邮件接收者地址、标题和内容,然后发送单个邮件服务 * @param {@link String} emailAddress * @param {@link String} subject * @param {@link String} content * @throws MessagingException */public static void sendSimpleEmail(String receiver, String subject, String content) throws MessagingException {JavaMailSender sender = (JavaMailSender) mailSender;MimeMessage mimeMessage = sender.createMimeMessage();MimeMessageHelper messageHelper = new MimeMessageHelper(mimeMessage, true, "UTF-8");messageHelper.setFrom("***@gmail.com");messageHelper.setTo(receiver);messageHelper.setSubject(subject);messageHelper.setText(content, true);sender.send(mimeMessage);}
?
?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] = "shupili141005@126.com";}long start = System.currentTimeMillis();for(String receiver: receiverList) {try {SimpleEmailSender.sendSimpleEmail(receiver, emailSubject, emailContent);} 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(List<String> receiverList, String subject, String content) throws MessagingException {JavaMailSender sender = (JavaMailSender) mailSender;int len = receiverList.size();MimeMessage[] mimeMessageList = new MimeMessage[len];// 注意:是数组类型MimeMessageHelper messageHelper = null;for(int i = 0; i < len; ++i) {mimeMessageList[i] = sender.createMimeMessage();messageHelper = new MimeMessageHelper(mimeMessageList[i], true, "UTF-8");messageHelper.setFrom("tucueservice@gmail.com");messageHelper.setTo(receiverList.get(i));messageHelper.setSubject(subject);messageHelper.setText(content, true);}sender.send(mimeMessageList);}?UserInfoAction.java 文件
// 用户 -> 批量邮件发送public String sendBatchEmail() {if(!emailReceiverList.equals("")) {// 发送用户邮件//String[] receiverList = emailReceiverList.split(",");List<String> receiverList = new ArrayList<String>(20);for(int i = 0; i < 20; ++i) {receiverList.add("shupili141005@126.com");}long start = System.currentTimeMillis();try {//SimpleEmailSender.sendBulkEmail(Arrays.asList(receiverList), emailSubject, emailContent);SimpleEmailSender.sendBulkEmail(receiverList, 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) 这个函数,所以也不知道存在第二种方案。后来突然发现有这个函数,就像能不能对先前的发送单个邮件服务加以改进,第二种方案也就是这样萌生的。