SpringBoot多郵件源發送郵件

前言

  最近因爲業務須要,須要使用郵件對用戶進行通知,可是單個郵箱有發送限制,當推送量過多時,常常會出現失敗,因而考慮使用多個郵箱進行發送,因爲spring-boot-starter-mail不支持同時配置多個郵件源,因此決定本身動手實現。java

實現思路

  spring-boot-starter-mail會根據spring.mail.xxx相關配置對JavaMailSender進行自動配置。可是隻支持單個郵箱。爲了實現多郵件源,能夠參照上述邏輯。在配置文件內配置好,多個郵件源。而後讀取配置文件,手動對JavaMailSender進行配置,並將其初始化完畢的JavaMailSender存儲容器內。而後發送時隨機取出JavaMailSender進行發送。spring

引入依賴

<dependency>
    <groupId>org.springframework.boot</groupId>
    <artifactId>spring-boot-starter-mail</artifactId>
</dependency>

郵件yml配置

替換實際的郵件配置數據庫

# 配置郵件
mail:
  configs:
    # 帳號
    - username: fapiao@QQ.com
      password: 123456
      host: smtp.qq.com
      port: 25
      protocol: smtp
      default-encoding: UTF-8
    # 帳號A
    - username: fapiaoa@QQ.com
      password: 123456
      host: smtp.qq.com
      port: 25
      protocol: smtp
      default-encoding: UTF-8

MailConfig

@Data
@Component
@ConfigurationProperties(prefix = "mail")
public class MailConfig {

    private List<MailProperties> configs;

    @Data
    public static class MailProperties {

        /**
         * 密碼
         */
        private String username;

        /**
         * 密碼
         */
        private String password;

        /**
         * host
         */
        private String host;

        /**
         * 端口
         */
        private Integer port;

        /**
         * 協議
         */
        private String protocol;

        /**
         * 默認編碼
         */
        private String defaultEncoding;

    }

}

MailSenderConfig

@Slf4j
@Component
@AllArgsConstructor
public class MailSenderConfig {

    private final MailConfig mailConfig;

    private final List<JavaMailSenderImpl> senderList;

    /**
     * 初始化 sender
     */
    @PostConstruct
    public void buildMailSender(){
        List<MailConfig.MailProperties> mailConfigs = mailConfig.getConfigs();
        log.info("初始化mailSender");
        mailConfigs.forEach(mailProperties -> {

            // 郵件發送者
            JavaMailSenderImpl javaMailSender = new JavaMailSenderImpl();
            javaMailSender.setDefaultEncoding(mailProperties.getDefaultEncoding());
            javaMailSender.setHost(mailProperties.getHost());
            javaMailSender.setPort(mailProperties.getPort());
            javaMailSender.setProtocol(mailProperties.getProtocol());
            javaMailSender.setUsername(mailProperties.getUsername());
            javaMailSender.setPassword(mailProperties.getPassword());

            // 添加數據
            senderList.add(javaMailSender);
        });
    }

    /**
     * 獲取MailSender
     * @return CustomMailSender
     */
    public JavaMailSenderImpl getSender(){
        if(senderList.isEmpty()){
            buildMailSender();
        }
        // 隨機返回一個JavaMailSender
        return senderList.get(new Random().nextInt(senderList.size()));
    }

    /**
     * 清理 sender
     */
    public void clear(){
        senderList.clear();
    }

}

MailService

public interface MailService {

    /**
     * 發送郵件
     * @return 返回 true 或者 false
     */
    boolean sendMail();

}

MailServiceImpl

@Service
@AllArgsConstructor
public class MailServiceImpl implements MailService {

    private final MailSenderConfig senderConfig;

    @Override
    public boolean sendMail() {

        JavaMailSenderImpl mailSender = senderConfig.getSender();

        //建立SimpleMailMessage對象
        SimpleMailMessage message = new SimpleMailMessage();
        //郵件發送人
        message.setFrom(Objects.requireNonNull(mailSender.getUsername()));
        //郵件接收人
        message.setTo("2583174414@qq.com");
        //郵件主題
        message.setSubject("測試郵件");
        //郵件內容
        message.setText("測試郵件內容");
        //發送郵件
        mailSender.send(message);

        return true;
    }
}

測試

@SpringBootTest
@RunWith(SpringRunner.class)
class MailServiceImplTest {

    @Autowired
    private MailServiceImpl mailService;

    @Test
    void sendMail() {
        mailService.sendMail();
    }
}

測試結果

注意的點

  • 須要檢查郵箱配置相關協議是否開啓。
  • 若是使用QQ郵箱進行發送,密碼不是郵箱密碼,而是受權碼。

拓展

  上述是將郵箱配置寫入配置文件,在沒有使用配置中心的狀況下,若是郵箱源被限制,更改起來相對麻煩。能夠將配置存入數據庫,在啓動的時候從數據庫進行加載。若是郵箱源發生更改,可直接更改數據庫郵箱源配置,而後調用MailSenderConfig.clear()方法,等待下次發送的時候,會從新初始化配置。api

結尾

  若是以爲對你有幫助,能夠多多評論,多多點贊哦,也能夠到個人主頁看看,說不定有你喜歡的文章,也能夠隨手點個關注哦,謝謝。dom

  我是不同的科技宅,天天進步一點點,體驗不同的生活。咱們下期見!ide

相關文章
相關標籤/搜索