SpringBoot 動(dòng)態(tài)配置郵箱發(fā)件人過程解析
前言
現(xiàn)在的消息模塊少不了郵件發(fā)送、短信發(fā)送和手機(jī)推送的功能。郵件發(fā)送的功能歷史最為悠久,也算的上爛大街的功能。一般在配置文件中設(shè)置好郵箱地址、賬號(hào)、密碼和發(fā)件服務(wù)器地址后便不會(huì)再去改動(dòng)。可是有的客戶卻希望人為指定發(fā)件人信息。這個(gè)需求并不過分,需要解決兩個(gè)大問題:如何在容器啟動(dòng)成功后重新修改發(fā)送郵件的Bean。如何在服務(wù)器重啟后,發(fā)件人依然是更改后的配置信息。這里記錄實(shí)現(xiàn)的步驟。

需求分析
一)、在未配置郵箱賬號(hào)時(shí),系統(tǒng)擁有默認(rèn)的郵箱發(fā)件人
二)、重新設(shè)置郵箱發(fā)件人后,需立即生效
三)、重啟服務(wù)器后,郵箱發(fā)件人依然是更改后的郵箱賬號(hào),而非默認(rèn)發(fā)件人
基礎(chǔ)的郵箱發(fā)送
郵箱發(fā)送的功能放在現(xiàn)在變得非常的簡單好用,一導(dǎo)二配三發(fā)送。😊
第一步:導(dǎo)入郵箱依賴包
compile('org.springframework.boot:spring-boot-starter-mail')
第二步:配置發(fā)件人郵箱信息
spring: mail: host: smtp.mxhichina.com username: itdragon@xx password: itdragon default-encoding: utf-8
第三步:發(fā)送郵件
@Autowired
lateinit var javaMailSender: JavaMailSender
fun pushMsgEmail(target: String, subject: String, content: String) {
if (target.isEmpty() || !Pattern.matches(REG_EMAIL_FORMAT, target)) return
val mailMsg = SimpleMailMessage()
mailMsg.setFrom(mailUserName!!)
mailMsg.setTo(target)
mailMsg.setSubject(subject)
mailMsg.setText(content)
javaMailSender.send(mailMsg)
}
可配置的郵件發(fā)送
這里的可配置值的是配置郵箱的發(fā)件人。首先我們要解決第一個(gè)問題,JavaMailSender 的Bean對象是在容器啟動(dòng)成功后就已經(jīng)注入到容器中。如何在容器啟動(dòng)后重新注入新的JavaMailSender 的Bean對象呢?
網(wǎng)上找了一些案例,他們都是通過銷毀Bean然后再重新創(chuàng)建Bean的方式實(shí)現(xiàn)。我有點(diǎn)好奇地是,為什么不直接將新的對象直接賦值從而替換原有的Bean對象?Spring默認(rèn)是單例模式,從Java內(nèi)存的角度看,這樣做似乎沒毛??!如果有不對的地方望不吝賜教😋
@Autowired
lateinit var javaMailSender: JavaMailSender
fun configEmail(postMailConfig: PostMailConfig): JavaMailSender {
val javaMailSender = JavaMailSenderImpl()
javaMailSender.host = postMailConfig.mailHost
javaMailSender.username = postMailConfig.mailUsername
javaMailSender.password = postMailConfig.mailPassword
val javaMailProperties = Properties()
javaMailProperties["mail.smtp.auth"] = true
javaMailProperties["mail.smtp.starttls.enable"] = true
javaMailProperties["mail.smtp.timeout"] = 5000
javaMailProperties["mail.smtp.socketFactory.class"] = "javax.net.ssl.SSLSocketFactory"
javaMailProperties["mail.smtp.socketFactory.port"] = "465"
javaMailProperties["mail.smtp.port"] = "465"
javaMailSender.javaMailProperties = javaMailProperties
this.javaMailSender = javaMailSender
return javaMailSender
}
再來解決第二個(gè)問題,服務(wù)器重啟后,默認(rèn)情況下依然會(huì)重新加載application.yml中的配置信息。這會(huì)出現(xiàn)郵箱發(fā)件人和實(shí)際配置的發(fā)件人不匹配的情況。其實(shí)這個(gè)問題也很好解決,加一個(gè)事件監(jiān)聽器,在容器初始化成功后執(zhí)行,根據(jù)之前保存的郵箱信息,重新配置郵箱。當(dāng)然,我們需要一張表記錄當(dāng)前發(fā)件人信息。
// 創(chuàng)建事件監(jiān)聽器
class ApplicationStartup : ApplicationListener<ContextRefreshedEvent> {
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)
}
}
// 注冊事件監(jiān)聽器
fun main(args: Array<String>) {
val springApplication = SpringApplication(StartApplication::class.java)
springApplication.addListeners(ApplicationStartup())
springApplication.run(*args)
}
最后發(fā)送郵件的代碼如下
@Service
class MailServiceImpl : MailService {
@Value("\${spring.mail.username}")
var mailUserName: String? = null
@Autowired
lateinit var javaMailSender: JavaMailSender
@Autowired
lateinit var systemBaseConfigMapper: SystemBaseConfigMapper
override fun pushMsgEmail(target: String, subject: String, content: String) {
if (target.isEmpty() || !Pattern.matches(REG_EMAIL_FORMAT, target)) return
val 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.mailHost
javaMailSender.username = postMailConfig.mailUsername
javaMailSender.password = postMailConfig.mailPassword
val javaMailProperties = Properties()
javaMailProperties["mail.smtp.auth"] = true
javaMailProperties["mail.smtp.starttls.enable"] = true
javaMailProperties["mail.smtp.timeout"] = 5000
javaMailProperties["mail.smtp.socketFactory.class"] = "javax.net.ssl.SSLSocketFactory"
javaMailProperties["mail.smtp.socketFactory.port"] = "465"
javaMailProperties["mail.smtp.port"] = "465"
javaMailSender.javaMailProperties = javaMailProperties
this.javaMailSender = javaMailSender
return javaMailSender
}
}
以上就是本文的全部內(nèi)容,希望對大家的學(xué)習(xí)有所幫助,也希望大家多多支持腳本之家。
- SpringBoot+JavaMailSender實(shí)現(xiàn)騰訊企業(yè)郵箱配置
- SpringBoot整合JavaMail通過阿里云企業(yè)郵箱發(fā)送郵件的實(shí)現(xiàn)
- springboot實(shí)現(xiàn)發(fā)送郵件(QQ郵箱為例)
- springboot實(shí)現(xiàn)郵箱驗(yàn)證碼功能
- SpringBoot使用郵箱發(fā)送驗(yàn)證碼實(shí)現(xiàn)注冊功能
- SpringBoot發(fā)送郵箱驗(yàn)證碼功能
- SpringBoot中快速實(shí)現(xiàn)郵箱發(fā)送代碼解析
- springboot實(shí)現(xiàn)發(fā)送QQ郵箱
相關(guān)文章
Java Map接口及其實(shí)現(xiàn)類原理解析
這篇文章主要介紹了Java Map接口及其實(shí)現(xiàn)類原理解析,文中通過示例代碼介紹的非常詳細(xì),對大家的學(xué)習(xí)或者工作具有一定的參考學(xué)習(xí)價(jià)值,需要的朋友可以參考下2020-03-03
Jboss Marshalling服務(wù)端無法接受消息
這篇文章主要介紹了Jboss Marshalling服務(wù)端無法接受消息,文中通過示例代碼介紹的非常詳細(xì),對大家的學(xué)習(xí)或者工作具有一定的參考學(xué)習(xí)價(jià)值,需要的朋友可以參考下2020-03-03
springboot2.0?@Slf4j?log?彩色日志配置輸出到文件
這篇文章主要介紹了springboot2.0 @Slf4j log日志配置輸出到文件(彩色日志),解決方式是使用了springboot原生自帶的一個(gè)log框架,結(jié)合實(shí)例代碼給大家講解的非常詳細(xì),需要的朋友可以參考下2023-08-08
使用Postman傳遞arraylist數(shù)據(jù)給springboot方式
這篇文章主要介紹了使用Postman傳遞arraylist數(shù)據(jù)給springboot方式,具有很好的參考價(jià)值,希望對大家有所幫助。如有錯(cuò)誤或未考慮完全的地方,望不吝賜教2021-12-12
利用Maven實(shí)現(xiàn)將代碼打包成第三方公共jar包
在項(xiàng)目開發(fā)過程中,我們經(jīng)常需要將一些公共方法提取出來,然后單獨(dú)封裝成一個(gè)第三方公共jar包,采用普通的方式打包后的jar,依賴的工程執(zhí)行編譯時(shí),卻提示找不到對應(yīng)的依賴包,那么如何將工程打包為可執(zhí)行jar包呢?下面向大家分享三種方法2022-10-10
Java實(shí)現(xiàn)默認(rèn)目錄查看與修改的方法
本項(xiàng)目介紹了Java如何獲取和修改默認(rèn)目錄,并通過示例代碼展示了如何在默認(rèn)目錄下創(chuàng)建和操作文件,盡管Java無法直接更改全局默認(rèn)目錄,但可以通過System.setProperty間接影響部分API的默認(rèn)行為,需要的朋友可以參考下2025-03-03

