23.3.使用Spring邮件抽象

优质
小牛编辑
122浏览
2023-12-01

23.3. 使用Spring邮件抽象

假设某个业务接口名为 OrderManager:

public interface OrderManager {

    void placeOrder(Order order);
}

同时有一个用例为:需要生成带有订单号的email信件, 并向客户发送该订单。 为此,我们会使用MailSender接口和SimpleMailMessage类。

请注意,通常情况下,我们在业务代码中使用接口而让Spring ioc容器负责组装我们需要的合作者。

以下是OrderManager的实现:

import org.springframework.mail.MailException;
import org.springframework.mail.MailSender;
import org.springframework.mail.SimpleMailMessage;

public class OrderManagerImpl implements OrderManager {

    private MailSender mailSender;
    private SimpleMailMessage message;

    public void setMailSender(MailSender mailSender) {
  this.mailSender = mailSender;
    }

    public void setMessage(SimpleMailMessage message) {
  this.message = message;
    }

    public void placeOrder(Order order) {

  // Do the business calculations...
  // Call the collaborators to persist the order...

  //Create a thread safe "sandbox" of the message
  SimpleMailMessage msg = new SimpleMailMessage(this.message);
  msg.setTo(order.getCustomer().getEmailAddress());
  msg.setText(
"Dear "
    + order.getCustomer().getFirstName()
    + order.getCustomer().getLastName()
    + ", thank you for placing order. Your order number is "
    + order.getOrderNumber());
  try{
mailSender.send(msg);
  }
  catch(MailException ex) {
//log it and go on
System.err.println(ex.getMessage());
  }
    }
}

上面的代码的bean定义应该是这样的:

<bean id="mailSender">
  <property name="host" value="mail.mycompany.com"/>
</bean>

<bean id="mailMessage">
  <property name="from" value="customerservice@mycompany.com"/>
  <property name="subject" value="Your order"/>
</bean>

<bean id="orderManager">
  <property name="mailSender" ref="mailSender"/>
  <property name="message" ref="mailMessage"/>
</bean>

下面是OrderManager接口的实现,使用了MimeMessagePreparator回调接口。 请注意这里的mailSender属性的类型为JavaMailSender,这样做是为了能够使用JavaMail的MimeMessage

import javax.mail.Message;
import javax.mail.MessagingException;
import javax.mail.internet.InternetAddress;
import javax.mail.internet.MimeMessage;

import javax.mail.internet.MimeMessage;
import org.springframework.mail.MailException;
import org.springframework.mail.javamail.JavaMailSender;
import org.springframework.mail.javamail.MimeMessagePreparator;

public class OrderManagerImpl implements OrderManager {

    private JavaMailSender mailSender;
    
    public void setMailSender(JavaMailSender mailSender) {
  this.mailSender = mailSender;
    }

    public void placeOrder(final Order order) {

  // Do the business calculations...
  // Call the collaborators to persist the order...
  
  MimeMessagePreparator preparator = new MimeMessagePreparator() {
  
public void prepare(MimeMessage mimeMessage) throws MessagingException {
  
    mimeMessage.setRecipient(Message.RecipientType.TO, 
new InternetAddress(order.getCustomer().getEmailAddress()));
    mimeMessage.setFrom(new InternetAddress("mail@mycompany.com"));
    mimeMessage.setText(
  "Dear "
+ order.getCustomer().getFirstName()
+ order.getCustomer().getLastName()
+ ", thank you for placing order. Your order number is "
+ order.getOrderNumber());
}
  };
  try {
mailSender.send(preparator);
  }
  catch (MailException ex) {
//log it and go on
System.err.println(ex.getMessage());
  }
    }
}

如果你想获得JavaMailMimeMessage的全部能力,你可以使用MimeMessagePreparator

注意

以上的邮件代码是一个横切关注点,是重构为定制SpringAOP advice的完美候选者,这样就可以在目标对象OrderManager合适的joinpoint中运行。请参阅第 7 章 使用Spring进行面向切面编程(AOP)章节。

23.3.1. 可插拔的MailSender实现

Spring直接提供两种MailSender的实现:标准的JavaMail实现,和基于Jason Hunter 编写的MailMessage类之上的实现,后者位于http://servlets.com/cos (com.oreilly.servlet)。进一步的资料请查阅相关Javadocs。