7.SpringBoot学习(七)——Spring Boot Email发送邮件

1.简介

1.1 概述

The Spring Framework provides an easy abstraction for sending email by using the JavaMailSender interface, and Spring Boot provides auto-configuration for it as well as a starter module.

Spring Framework 通过使用 JavaMailSender 接口提供了用于发送电子邮件的简单抽象,Spring Boot 为它以及启动程序模块提供了自动装配。

1.2 特点

If spring.mail.host and the relevant libraries (as defined by spring-boot-starter-mail) are available, a default JavaMailSender is created if none exists. The sender can be further customized by configuration items from the spring.mail namespace. See MailProperties for more details.

如果有 “ spring.mail.host” 和相关的库(由“ spring-boot-starter-mail”定义)可用,那么如果不存在默认的“ JavaMailSender”,则会创建一个。可以通过 spring.mail 命名空间中的配置项进一步定制发送者。参考 MailProperties 以获取更多详细信息。

@ConfigurationProperties(prefix = "spring.mail")
public class MailProperties {
    private static final Charset DEFAULT_CHARSET;
    private String host;
    private Integer port;
    private String username;
    private String password;
    private String protocol = "smtp";
    private Charset defaultEncoding;
    private Map<String, String> properties;
    private String jndiName;
    // get&set
}

2.演示环境

  1. JDK 1.8.0_201
  2. Spring Boot 2.2.0.RELEASE
  3. 构建工具(apache maven 3.6.3)
  4. 开发工具(IntelliJ IDEA )

3.演示代码

3.1 代码说明

测试 spring boot 发送 email

3.2 代码结构

image-20200719163127844

3.3 maven 依赖

<dependencies>
    <dependency>
        <groupId>org.springframework.boot</groupId>
        <artifactId>spring-boot-starter-mail</artifactId>
    </dependency>
    <dependency>
        <groupId>org.springframework.boot</groupId>
        <artifactId>spring-boot-starter-web</artifactId>
    </dependency>
    <dependency>
        <groupId>org.springframework.boot</groupId>
        <artifactId>spring-boot-starter-test</artifactId>
        <scope>test</scope>
    </dependency>
</dependencies>

3.4 配置文件

spring.application.name=spring-boot-email

spring.mail.host=pop.qq.com
spring.mail.username=aaa@123.com
spring.mail.password=eiosdal
spring.mail.default-encoding=UTF-8

mail.from.addr=aaa@123.com

3.5 java代码

EmailSenderService.java

public interface EmailSenderService {

    /**
     * 发送简单邮件
     * @param to 目的地
     * @param subject 主题
     * @param content 内容
     */
    void sendSimpleEmail(String to, String subject, String content);

    /**
     * 发送含有html内容的邮件
     * @param to 目的地
     * @param subject 主题
     * @param content 内容
     */
    void sendHtmlEmail(String to, String subject, String content);

    /**
     * 发送带有附件的邮件
     * @param to 目的地
     * @param subject 主题
     * @param content 内容
     * @param filePath 附件路径
     */
    void sendEmailWithAttachments(String to, String subject, String content, String filePath);

    /**
     * 发送带有静态资源(图片)的邮件
     * @param to 目的地
     * @param subject 主题
     * @param content 内容
     * @param resPath 资源路径
     * @param resId 资源id
     */
    void sendEmailWithInlineResource(String to, String subject, String content, String resPath, String resId);
}

EmailSenderServiceImpl.java

@Service
public class EmailSenderServiceImpl implements EmailSenderService {

    @Resource
    private JavaMailSender mailSender;

    @Value("${mail.from.addr}")
    private String from;

    @Override
    public void sendSimpleEmail(String to, String subject, String content) {
        SimpleMailMessage message = new SimpleMailMessage();
        message.setFrom(from);
        message.setTo(to);
        message.setSubject(subject);
        message.setText(content);
        mailSender.send(message);
    }

    @Override
    public void sendHtmlEmail(String to, String subject, String content) {
        try {
            MimeMessage mimeMessage = mailSender.createMimeMessage();
            MimeMessageHelper messageHelper = new MimeMessageHelper(mimeMessage, true);
            messageHelper.setFrom(from);
            messageHelper.setTo(to);
            messageHelper.setSubject(subject);
            messageHelper.setText(content, true);
            mailSender.send(mimeMessage);
        } catch (MessagingException e) {
            e.printStackTrace();
        }
    }

    @Override
    public void sendEmailWithAttachments(String to, String subject, String content, String filePath) {
        try {
            MimeMessage mimeMessage = mailSender.createMimeMessage();
            MimeMessageHelper helper = new MimeMessageHelper(mimeMessage, true);
            helper.setFrom(from);
            helper.setTo(to);
            helper.setSubject(subject);
            helper.setText(content, true);

            FileSystemResource resource = new FileSystemResource(new File(filePath));
            String fileName = filePath.substring(filePath.indexOf(File.separator));
            helper.addAttachment(fileName, resource);
            mailSender.send(mimeMessage);
        } catch (MessagingException e) {
            e.printStackTrace();
        }
    }

    @Override
    public void sendEmailWithInlineResource(String to, String subject, String content, String resPath, String resId) {
        try {
            MimeMessage mimeMessage = mailSender.createMimeMessage();
            MimeMessageHelper helper = new MimeMessageHelper(mimeMessage, true);
            helper.setFrom(from);
            helper.setTo(to);
            helper.setSubject(subject);
            helper.setText(content, true);

            FileSystemResource resource = new FileSystemResource(new File(resPath));
            helper.addInline(resId, resource);
            mailSender.send(mimeMessage);
        } catch (MessagingException e) {
            e.printStackTrace();
        }
    }
}

3.6 git 地址

spring-boot/spring-boot-05-basis/spring-boot-email

4.效果展示

使用测试类进行测试,测试时替换成实际的邮件地址和内容

@RunWith(SpringRunner.class)
@SpringBootTest
public class SpringBootEmailApplicationTests {

    @Autowired
    private EmailSenderService senderService;

    @Test
    public void contextLoads() {}

    @Test
    public void test_send_simpleEmail() {
        senderService.sendSimpleEmail("bbb@324.com", "test", "test");
    }
}

5.源码分析

5.1 Email 自动装配

JavaMailSender 仅有一个实现 JavaMailSenderImpl

image-20200719163739485

在 Mail 的自动装配类 MailSenderAutoConfiguration 中有如下定义

@Configuration(proxyBeanMethods = false)
@ConditionalOnClass({ MimeMessage.class, MimeType.class, MailSender.class })
@ConditionalOnMissingBean(MailSender.class)
@Conditional(MailSenderCondition.class)
@EnableConfigurationProperties(MailProperties.class)
@Import({ MailSenderJndiConfiguration.class, MailSenderPropertiesConfiguration.class })
public class MailSenderAutoConfiguration {

    static class MailSenderCondition extends AnyNestedCondition {

        MailSenderCondition() {
            super(ConfigurationPhase.PARSE_CONFIGURATION);
        }

        @ConditionalOnProperty(prefix = "spring.mail", name = "host")
        static class HostProperty {

        }

        @ConditionalOnProperty(prefix = "spring.mail", name = "jndi-name")
        static class JndiNameProperty {

        }
    }
}

MailSenderAutoConfiguration 通过 @Import 对 MailSenderJndiConfiguration 和 MailSenderPropertiesConfiguration 进行导入,这两个类中声明了 JavaMailSenderImpl 对象

@Configuration(proxyBeanMethods = false)
@ConditionalOnClass(Session.class)
@ConditionalOnProperty(prefix = "spring.mail", name = "jndi-name")
@ConditionalOnJndi
class MailSenderJndiConfiguration {

    private final MailProperties properties;

    MailSenderJndiConfiguration(MailProperties properties) {
        this.properties = properties;
    }

    @Bean
    JavaMailSenderImpl mailSender(Session session) {
        JavaMailSenderImpl sender = new JavaMailSenderImpl();
        sender.setDefaultEncoding(this.properties.getDefaultEncoding().name());
        sender.setSession(session);
        return sender;
    }

    @Bean
    @ConditionalOnMissingBean
    Session session() {
        String jndiName = this.properties.getJndiName();
        try {
            return JndiLocatorDelegate.createDefaultResourceRefLocator().lookup(jndiName, Session.class);
        }
        catch (NamingException ex) {
            throw new IllegalStateException(String.format("Unable to find Session in JNDI location %s", jndiName), ex);
        }
    }
}

6.参考

  1. 官方文档-Spring Boot Features/Email
posted @ 2020-07-19 22:20  Soulballad  阅读(498)  评论(0编辑  收藏  举报