SpringBoot实现动态配置邮箱发件人的过程解析
创始人
2024-12-22 10:22:18
0次

前言

现在的消息模块少不了邮件发送、短信发送和手机推送的功能。邮件发送的功能历史最为悠久,也算的上烂大街的功能。一般在配置文件中设置好邮箱地址、账号、密码和发件服务器地址后便不会再去改动。可是有的客户却希望人为指定发件人信息。这个需求并不过分,需要解决两个大问题:如何在容器启动成功后重新修改发送邮件的Bean。如何在服务器重启后,发件人依然是更改后的配置信息。这里记录实现的步骤。

需求分析

一)、在未配置邮箱账号时,系统拥有默认的邮箱发件人

二)、重新设置邮箱发件人后,需立即生效

三)、重启服务器后,邮箱发件人依然是更改后的邮箱账号,而非默认发件人

基础的邮箱发送邮箱发送的功能放在现在变得非常的简单好用,一导二配三发送。?

第一步:导入邮箱依赖包

compile('org.springframework.boot:spring-boot-starter-mail')第二步:配置发件人邮箱信息

spring:mail:host: smtp.mxhichina.comusername: itdragon@xxpassword: itdragondefault-encoding: utf-8第三步:发送邮件

@Autowiredlateinit var javaMailSender: JavaMailSender

fun pushMsgEmail(target: String, subject: String, content: String) {if (target.isEmpty() || !Pattern.matches(REG_EMAIL_FORMAT, target)) returnval mailMsg = SimpleMailMessage()mailMsg.setFrom(mailUserName!!)mailMsg.setTo(target)mailMsg.setSubject(subject)mailMsg.setText(content)javaMailSender.send(mailMsg)}可配置的邮件发送这里的可配置值的是配置邮箱的发件人。首先我们要解决第一个问题,JavaMailSender 的Bean对象是在容器启动成功后就已经注入到容器中。如何在容器启动后重新注入新的JavaMailSender 的Bean对象呢?网上找了一些案例,他们都是通过销毁Bean然后再重新创建Bean的方式实现。我有点好奇地是,为什么不直接将新的对象直接赋值从而替换原有的Bean对象?Spring默认是单例模式,从Java内存的角度看,这样做似乎没毛病!如果有不对的地方望不吝赐教?

@Autowiredlateinit var javaMailSender: JavaMailSender

fun configEmail(postMailConfig: PostMailConfig): JavaMailSender {val javaMailSender = JavaMailSenderImpl()javaMailSender.host = postMailConfig.mailHostjavaMailSender.username = postMailConfig.mailUsernamejavaMailSender.password = postMailConfig.mailPasswordval javaMailProperties = Properties()javaMailProperties["mail.smtp.auth"] = truejavaMailProperties["mail.smtp.starttls.enable"] = truejavaMailProperties["mail.smtp.timeout"] = 5000javaMailProperties["mail.smtp.socketFactory.class"] = "javax.net.ssl.SSLSocketFactory"javaMailProperties["mail.smtp.socketFactory.port"] = "465"javaMailProperties["mail.smtp.port"] = "465"javaMailSender.javaMailProperties = javaMailPropertiesthis.javaMailSender = javaMailSenderreturn javaMailSender}再来解决第二个问题,服务器重启后,默认情况下依然会重新加载application.yml中的配置信息。这会出现邮箱发件人和实际配置的发件人不匹配的情况。其实这个问题也很好解决,加一个事件监听器,在容器初始化成功后执行,根据之前保存的邮箱信息,重新配置邮箱。当然,我们需要一张表记录当前发件人信息。

// 创建事件监听器class ApplicationStartup : ApplicationListener {override fun onApplicationEvent(contextRefreshedEvent: ContextRefreshedEvent) {val systemBaseConfigMapper = contextRefreshedEvent.applicationContext.getBean(SystemBaseConfigMapper::class.java)val postMailConfig = systemBaseConfigMapper.selectByMail()val mailService = contextRefreshedEvent.applicationContext.getBean(MailService::class.java)mailService.configEmail(postMailConfig)}}

// 注册事件监听器fun main(args: Array) {val springApplication = SpringApplication(StartApplication::class.java)springApplication.addListeners(ApplicationStartup())springApplication.run(*args)}最后发送邮件的代码如下

@Serviceclass MailServiceImpl : MailService {

@Value("\${spring.mail.username}")var mailUserName: String? = null

@Autowiredlateinit var javaMailSender: JavaMailSender@Autowiredlateinit var systemBaseConfigMapper: SystemBaseConfigMapper

override fun pushMsgEmail(target: String, subject: String, content: String) {if (target.isEmpty() || !Pattern.matches(REG_EMAIL_FORMAT, target)) returnval mailMsg = SimpleMailMessage()mailMsg.setFrom(mailUserName!!)mailMsg.setTo(target)mailMsg.setSubject(subject)mailMsg.setText(content)try {systemBaseConfigMapper.selectByMailName()?.let {mailMsg.setFrom(it.value!!)}javaMailSender.send(mailMsg)} catch (e: Exception) {e.printStackTrace()}}

override fun configEmail(postMailConfig: PostMailConfig): JavaMailSender {val javaMailSender = JavaMailSenderImpl()javaMailSender.host = postMailConfig.mailHostjavaMailSender.username = postMailConfig.mailUsernamejavaMailSender.password = postMailConfig.mailPasswordval javaMailProperties = Properties()javaMailProperties["mail.smtp.auth"] = truejavaMailProperties["mail.smtp.starttls.enable"] = truejavaMailProperties["mail.smtp.timeout"] = 5000javaMailProperties["mail.smtp.socketFactory.class"] = "javax.net.ssl.SSLSocketFactory"javaMailProperties["mail.smtp.socketFactory.port"] = "465"javaMailProperties["mail.smtp.port"] = "465"javaMailSender.javaMailProperties = javaMailPropertiesthis.javaMailSender = javaMailSenderreturn javaMailSender}

}

相关内容

热门资讯

空调连续工作多久需要停机休息 空调连续工作的时间取决于多个因素,包括空调的型号、功率、使用环境和维护情况等。一般来说,空调可以连续...
空调哪个符号是除湿的 空调除湿功能通常用一个水滴形状的符号表示。不同品牌和型号的空调遥控器可能会有所差异,但一般来说,除湿...
格力空调多长时间加一次氟利昂 1、一般情况下,空调对氟利昂的使用量是非常小的,所以在空调使用了四年左右的时候再考虑加也没问题。2、...
空调用多长时间需要加氟一次 一般情况下是五年。当出现以下这几种情况时,空调才需要加氟。1、空调的室内机和室外机各有两个接口,当接...
格调生活·C标思享荟:卡萨帝在... 9月12日的郑州龙湖金融岛,夜风轻拂,灯光璀璨。“C标时刻共传奇——卡萨帝思享荟暨20周年品牌盛典郑...
品牌价值破千亿、高端份额持续领... 9月12日,“C标时刻共传奇——卡萨帝思享荟暨20周年品牌盛典郑州站”在郑州龙湖金融岛举办。2026...
空调主板坏了修800还是换新的 空调主板坏了是修还是换新,需要考虑多个因素,以下是一些建议:1. 维修成本:如果维修费用较低,比如 ...
空调开多久需要休息多长时间 问题:空调开多久需要休息多长时间回答:1、在使用空调的过程中,一般空调开7~8个小时左右需要休息2~...
中央空调多长时间清洗一次 1、一般空调开机前清洗一次即可,空调开机中间时段再清洗一次,空调关机时清洗一次,这样比较合理。2、空...
中央空调氟利昂多久加一次 看空调制热和制冷程度,很多人的观点认为氟利昂必须一年放一次,其实这个观点是错误的,理解上面有点偏差,...