天天看點

SpringBoot多郵件源發送郵件

SpringBoot多郵件源發送郵件

前言

  最近由于業務需要,需要使用郵件對使用者進行通知,但是單個郵箱有發送限制,當推送量過多時,經常會出現失敗,于是考慮使用多個郵箱進行發送,由于

spring-boot-starter-mail

不支援同時配置多個郵件源,是以決定自己動手實作。

實作思路

  

spring-boot-starter-mail

會根據

spring.mail.xxx

相關配置對

JavaMailSender

進行自動配置。但是隻支援單個郵箱。為了實作多郵件源,可以參照上述邏輯。在配置檔案内配置好,多個郵件源。然後讀取配置檔案,手動對

JavaMailSender

進行配置,并将其初始化完畢的

JavaMailSender

存儲容器内。然後發送時随機取出

JavaMailSender

進行發送。

引入依賴

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

郵件yml配置

替換實際的郵件配置

# 配置郵件
mail:
  configs:
    # 賬号
    - username: [email protected]
      password: 123456
      host: smtp.qq.com
      port: 25
      protocol: smtp
      default-encoding: UTF-8
    # 賬号A
    - username: [email protected]
      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("[email protected]");
        //郵件主題
        message.setSubject("測試郵件");
        //郵件内容
        message.setText("測試郵件内容");
        //發送郵件
        mailSender.send(message);

        return true;
    }
}           

測試

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

    @Autowired
    private MailServiceImpl mailService;

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

測試結果

SpringBoot多郵件源發送郵件

注意的點

  • 需要檢查郵箱配置相關協定是否開啟。
  • 如果使用QQ郵箱進行發送,密碼不是郵箱密碼,而是授權碼。

拓展

  上述是将郵箱配置寫入配置檔案,在沒有使用配置中心的情況下,如果郵箱源被限制,更改起來相對麻煩。可以将配置存入資料庫,在啟動的時候從資料庫進行加載。如果郵箱源發生更改,可直接更改資料庫郵箱源配置,然後調用

MailSenderConfig.clear()

方法,等待下次發送的時候,會重新初始化配置。

結尾

  如果覺得對你有幫助,可以多多評論,多多點贊哦,也可以到我的首頁看看,說不定有你喜歡的文章,也可以随手點個關注哦,謝謝。

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