通过Internet发送邮件,可能会在网络传输上面使用较多的时间,如果调用发送邮件的线程与发送邮件线程是同一个的话,那么有可能会照成系统等待较长的时间而无法继续执行,影响系统效率。
那么这时可考虑使用多线程,实现异步发送,而不用等待邮件发送者的返回。
首先,是发送邮件的抽象任务类。其子类负责发送邮件操作。
public abstract class AbstractTask implements Runnable {
private IEmailSenderListener iEmailSenderListener;
private Log log = LogFactory.getLog(AbstractTask.class);
/* (non-Javadoc)
* @see java.lang.Runnable#run()
*/
@Override
public void run() {
if(iEmailSenderListener != null){
// 操作开始响应事件
iEmailSenderListener.beforeSendEmail();
}
boolean flag = false;
try{
flag = doAction();
}catch(Exception e){
if(iEmailSenderListener != null){
iEmailSenderListener.catchException(e);
}
log.error(e,e.fillInStackTrace());
e.printStackTrace();
}
if(iEmailSenderListener != null){
// 操作完成之后
iEmailSenderListener.afterSendEmail(flag);
}
}
public abstract boolean doAction() throws Exception;
}
发送邮件实现类:
public class EmailSendTask extends AbstractTask{
private JavaMailSender javaMailSender;
SimpleMailMessage simpleMailMessage;
MimeMessage mimeMessage;
public EmailSendTask(SimpleMailMessage simpleMailMessage,JavaMailSender javaMailSender){
this.simpleMailMessage = simpleMailMessage;
this.javaMailSender = javaMailSender;
}
public EmailSendTask(MimeMessage mimeMessage,JavaMailSender javaMailSender){
this.mimeMessage = mimeMessage;
this.javaMailSender = javaMailSender;
}
/*
* (non-Javadoc)
* @see net.bingosoft.common.email.task.AbstractTask#doAction()
*/
@Override
public boolean doAction() throws Exception {
boolean flag = true;
if(this.simpleMailMessage != null){
javaMailSender.send(this.simpleMailMessage);
}else if(this.mimeMessage != null){
javaMailSender.send(this.mimeMessage);
}
return flag;
}
}
创建一个线程池,用户实现多线程调用邮件发送类。通过concurrent包实现
public class EmailExecutorPool implements InitializingBean{
/**线程池数量,spring配置文件中配置*/
private Integer poolSize;
private ExecutorService service;
/**
* 在Bean被初始化完成之后,初始化线程大小
*/
public void afterPropertiesSet() throws Exception {
if(poolSize == null){
service = Executors.newCachedThreadPool();
}else{
service = Executors.newFixedThreadPool(poolSize);
}
}
}
实际调用发送类:
public class EmailSender {
/**注入MailSender*/
private JavaMailSender javaMailSender;
/**注入线程池*/
private EmailExecutorPool emailExecutorPool;
/**设置发件人*/
private String from;
private Log log = LogFactory.getLog(EmailSender.class);
/**
* 发送简单邮件
* @param email
*/
public void sendMail(EmailEntity email){
if(null == email){
if(log.isDebugEnabled()){
log.debug("需要发送的邮件抽象类为空");
}
return;
}
SimpleMailMessage simpleMailMessage = new SimpleMailMessage();
simpleMailMessage.setTo(email.getTo());
simpleMailMessage.setSubject(email.getSubject());
simpleMailMessage.setText(email.getText());
simpleMailMessage.setFrom(from);
//调用线程发送邮件
emailExecutorPool.getService().execute(new EmailSendTask(simpleMailMessage,javaMailSender));
}
/**
* 发送带附件和图片的邮件
* @param email
*/
public void sendMimeMail(EmailEntity email) throws Exception{
if(null == email){
if(log.isDebugEnabled()){
log.debug("需要发送的邮件抽象类为空");
}
return;
}
MimeMessage mimeMessage = javaMailSender.createMimeMessage();
MimeMessageHelper helper = new MimeMessageHelper(mimeMessage,true,"utf-8");
//收件人
helper.setTo(email.getTo());
//邮件主题
helper.setSubject(email.getSubject());
//邮件内容
helper.setText(email.getText());
//发件人
helper.setFrom(from);
this.addAttachmentOrImg(helper, email.getAttachments(), true);
this.addAttachmentOrImg(helper, email.getImgs(), false);
emailExecutorPool.getService().execute(new EmailSendTask(mimeMessage,javaMailSender));
}
/**
* 在邮件中增加附件或者图片
* @param helper
* @param map
* @param isAttachment 是否是附件
*/
@SuppressWarnings("rawtypes")
public void addAttachmentOrImg(MimeMessageHelper helper, Map map, boolean isAttachment) throws Exception{
for(Iterator it = map.entrySet().iterator();it.hasNext();){
Map.Entry entry = (Map.Entry) it.next();
String key = (String) entry.getKey();
String value = (String) entry.getValue();
if(StringUtils.isNotBlank(key) && StringUtils.isNotBlank(value)){
FileSystemResource file = new FileSystemResource(new File(value));
if(!file.exists()) continue;
try{
if(isAttachment){
helper.addAttachment(MimeUtility.encodeWord(key), file);
}else{
helper.addInline(MimeUtility.encodeWord(key), file);
}
}catch(UnsupportedEncodingException e){
log.debug("附件中文转码错误");
e.printStackTrace();
}
}
}
}
}
测试代码:
@Controller
@RequestMapping("/test.do")
public class TestController {
@Autowired
private EmailSender emailSender;
private Log log = LogFactory.getLog(TestController.class);
@RequestMapping(params = "method=sendemail")
public void sendEmail(HttpServletRequest req, HttpServletResponse resp){
System.out.println("sending email ...");
log.debug("sending email ...");
EmailEntity entity = new EmailEntity();
entity.setSubject("test");
entity.setText("测试内容");
entity.setTo("**@qq.com");
emailSender.sendMail(entity);
}
}