Spring-mail(2)

2. 分析Spring mail的内部源码
我们写的DummySpringMail类中的sendMsg()方法,将实际要发送的消息通过MailSender的send方法发送了。我们看一下send方法内部的实现:
public void send(SimpleMailMessage simpleMessage) throws MailException {
		send(new SimpleMailMessage[] { simpleMessage });
	}

	public void send(SimpleMailMessage[] simpleMessages) throws MailException {
		List<MimeMessage> mimeMessages = new ArrayList<MimeMessage>(simpleMessages.length);
		for (SimpleMailMessage simpleMessage : simpleMessages) {
			MimeMailMessage message = new MimeMailMessage(createMimeMessage());
			simpleMessage.copyTo(message);
			mimeMessages.add(message.getMimeMessage());
		}
		doSend(mimeMessages.toArray(new MimeMessage[mimeMessages.size()]), simpleMessages);
	}


我们可以看到,这里将发送的SimpleMailMessage消息转化为了javax.mail.internet.MimeMessage,这正是我们前文提到的。继续看doSend()方法:
protected void doSend(MimeMessage[] mimeMessages, Object[] originalMessages) throws MailException {
		Map<Object, Exception> failedMessages = new LinkedHashMap<Object, Exception>();

		Transport transport;
		try {
			transport = getTransport(getSession()); //这里,spring是通过javax.mail.Session的getInstance(Properties props)方法创建的实例。
			transport.connect(getHost(), getPort(), getUsername(), getPassword()); //连接到我们配置的邮件服务器。
		}
		catch (AuthenticationFailedException ex) {
			throw new MailAuthenticationException(ex);
		}
		catch (MessagingException ex) {
			// Effectively, all messages failed...
			for (int i = 0; i < mimeMessages.length; i++) {
				Object original = (originalMessages != null ? originalMessages[i] : mimeMessages[i]);
				failedMessages.put(original, ex);
			}
			throw new MailSendException("Mail server connection failed", ex, failedMessages);
		}

		try {
			for (int i = 0; i < mimeMessages.length; i++) {
				MimeMessage mimeMessage = mimeMessages[i];
				try {
					if (mimeMessage.getSentDate() == null) {
						mimeMessage.setSentDate(new Date());
					}
					String messageId = mimeMessage.getMessageID();
					mimeMessage.saveChanges();
					if (messageId != null) {
						// Preserve explicitly specified message id...
						mimeMessage.setHeader(HEADER_MESSAGE_ID, messageId); // 添加消息头部信息
					}
					transport.sendMessage(mimeMessage, mimeMessage.getAllRecipients()); //这里是发送mail的实际代码
				}
				catch (MessagingException ex) {
					Object original = (originalMessages != null ? originalMessages[i] : mimeMessage);
					failedMessages.put(original, ex);
				}
			}
		}
		finally {
			try {
				transport.close();
			}
			catch (MessagingException ex) {
				if (!failedMessages.isEmpty()) {
					throw new MailSendException("Failed to close server connection after message failures", ex,
							failedMessages);
				}
				else {
					throw new MailSendException("Failed to close server connection after message sending", ex);
				}
			}
		}

		if (!failedMessages.isEmpty()) {
			throw new MailSendException(failedMessages);
		}
	}


看一下创建Session实例的org.springframework.mail.javamail.JavaMailSenderImpl类的getSession()方法:
public synchronized Session getSession() {
		if (this.session == null) {
			this.session = Session.getInstance(this.javaMailProperties);
		}
		return this.session;
	}


这里并没有真正的创建Session实例,而是执行了javax.mail.Session中的getInstance()方法来创建实例的。
 public static Session getInstance(Properties props) {
	return new Session(props, null);
    }


到这里,从建立Session,到解析字符邮件地址为Address类型,去构造消息Message实例,最后通过Transport类的send方法发送消息。spring中的mail发送邮件细节已经全部完毕了。那么,apache中的commons-email,发送邮件的原理也就彼此彼此!

你可能感兴趣的:(apache,spring)