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: 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()
方法,等待下次发送的时候,会重新初始化配置。
结尾
如果觉得对你有帮助,可以多多评论,多多点赞哦,也可以到我的主页看看,说不定有你喜欢的文章,也可以随手点个关注哦,谢谢。
我是不一样的科技宅,每天进步一点点,体验不一样的生活。我们下期见!
推荐阅读
SpringBoot实现热部署两种方式!
小宅作为一个Java程序员,在日常的工作中,经常需要修改代码,然后重启服务,在验证代码是否生效。如果是小项目还好,重启速度比较快,等待时间比较短。但是随着项目逐渐变大,并且被拆分成多个服务时,改动一些...
不一样的科技宅赞 2阅读 3.8k评论 1
Java 编译器 javac 及 Lombok 实现原理解析
javac 是 Java 代码的编译器12,初学 Java 的时候就应该接触过。本文整理一些 javac 相关的高级用法。Lombok 库,大家平常一直在使用,但可能并不知道实现原理解析,其实 Lombok 实现上依赖的是 Java 编译器的注...
nullwy赞 10阅读 5.9k
与RabbitMQ有关的一些知识
工作中用过一段时间的Kafka,不过主要还是RabbitMQ用的多一些。今天主要来讲讲与RabbitMQ相关的一些知识。一些基本概念,以及实际使用场景及一些注意事项。
lpe234赞 8阅读 1.8k
spring boot 锁
由于当前的项目中由于多线程操作同一个实体,会出现数据覆盖的问题,后保存的实体把先保存的实体的数据给覆盖了。于是查找了锁的实现的几种方式。但写到最后发现,其实自己可以写sql 更新需要更新的字段即可,这...
weiewiyi赞 3阅读 9.1k
Git操作不规范,战友提刀来相见!
年终奖都没了,还要扣我绩效,门都没有,哈哈。这波骚Git操作我也是第一次用,担心闪了腰,所以不仅做了备份,也做了笔记,分享给大家。问题描述小A和我在同时开发一个功能模块,他在优化之前的代码逻辑,我在开...
王中阳Go赞 5阅读 1.8k评论 2
Redis 发布订阅模式:原理拆解并实现一个消息队列
“65 哥,如果你交了个漂亮小姐姐做女朋友,你会通过什么方式将这个消息广而告之给你的微信好友?““那不得拍点女朋友的美照 + 亲密照弄一个九宫格图文消息在朋友圈发布大肆宣传,暴击单身狗。”像这种 65 哥通过朋...
码哥字节赞 5阅读 1.1k
NB的Github项目,看到最后一个我惊呆了!
最近看到不少好玩的、实用的 Github 项目,就来给大家推荐一把。中国制霸生成器最近在朋友圈非常火的一个小网站,可以在线标记 居住、短居、游玩、出差、路过 标记后可生成图片进行社区分享,标记过的信息会记录...
艾小仙赞 5阅读 1.5k评论 1
**粗体** _斜体_ [链接](http://example.com) `代码` - 列表 > 引用
。你还可以使用@
来通知其他用户。