
前言
最近由于業務需要,需要使用郵件對使用者進行通知,但是單個郵箱有發送限制,當推送量過多時,經常會出現失敗,于是考慮使用多個郵箱進行發送,由于
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();
}
}
測試結果
注意的點
- 需要檢查郵箱配置相關協定是否開啟。
- 如果使用QQ郵箱進行發送,密碼不是郵箱密碼,而是授權碼。
拓展
上述是将郵箱配置寫入配置檔案,在沒有使用配置中心的情況下,如果郵箱源被限制,更改起來相對麻煩。可以将配置存入資料庫,在啟動的時候從資料庫進行加載。如果郵箱源發生更改,可直接更改資料庫郵箱源配置,然後調用
MailSenderConfig.clear()
方法,等待下次發送的時候,會重新初始化配置。
結尾
如果覺得對你有幫助,可以多多評論,多多點贊哦,也可以到我的首頁看看,說不定有你喜歡的文章,也可以随手點個關注哦,謝謝。
我是不一樣的科技宅,每天進步一點點,體驗不一樣的生活。我們下期見!