SpringBoot 動態配置郵箱發件人

點擊上方 "程序員小樂"關注, 星標或置頂一起成長

第一時間與你相約

每日英文

Women must be able to deal with lies, tolerate perfunctory responses, endure deceptions, forget promises and let go of everything.

人一定要經得起假話, 受得起敷衍, 忍得住欺騙, 忘得了諾言, 放得下一切。


每日掏心話

有種痛,只能獨自咀嚼,慢慢回味。生命中的許多時候,不幸會突然降臨,讓我們措手不及。


來自:ITDragon龍 | 責編:樂樂

鏈接:cnblogs.com/itdragon/p/11239771.html#4339461

SpringBoot 動態配置郵箱發件人
程序員小樂(ID:study_tech)第 723 次推文 圖片來自網絡


往日回顧:關於如何掙錢的35條建議!萬字長文


正文


現在的消息模塊少不了郵件發送、短信發送和手機推送的功能。郵件發送的功能歷史最為悠久,也算的上爛大街的功能。一般在配置文件中設置好郵箱地址、賬號、密碼和發件服務器地址後便不會再去改動。可是有的客戶卻希望人為指定發件人信息。這個需求並不過分,需要解決兩個大問題:如何在容器啟動成功後重新修改發送郵件的Bean。如何在服務器重啟後,發件人依然是更改後的配置信息。這裡記錄實現的步驟。

SpringBoot 動態配置郵箱發件人

一、需求分析

一)、在未配置郵箱賬號時,系統擁有默認的郵箱發件人

二)、重新設置郵箱發件人後,需立即生效

三)、重啟服務器後,郵箱發件人依然是更改後的郵箱賬號,而非默認發件人

二、基礎的郵箱發送

郵箱發送的功能放在現在變得非常的簡單好用,一導二配三發送。

第一步:導入郵箱依賴包

compile('org.springframework.boot:spring-boot-starter-mail')

第二步:配置發件人郵箱信息

spring:
mail:
host: smtp.mxhichina.com
username: itdragon@xx
password: itdragon
default-encoding: utf-8

第三步:發送郵件

@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)
}

三、可配置的郵件發送

這裡的可配置值的是配置郵箱的發件人。首先我們要解決第一個問題,JavaMailSender 的Bean對象是在容器啟動成功後就已經注入到容器中。如何在容器啟動後重新注入新的JavaMailSender 的Bean對象呢?網上找了一些案例,他們都是通過銷燬Bean然後再重新創建Bean的方式實現。我有點好奇地是,為什麼不直接將新的對象直接賦值從而替換原有的Bean對象?Spring默認是單例模式,從Java內存的角度看,這樣做似乎沒毛病!如果有不對的地方望不吝賜教

@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
}

再來解決第二個問題,服務器重啟後,默認情況下依然會重新加載application.yml中的配置信息。這會出現郵箱發件人和實際配置的發件人不匹配的情況。其實這個問題也很好解決,加一個事件監聽器,在容器初始化成功後執行,根據之前保存的郵箱信息,重新配置郵箱。當然,我們需要一張表記錄當前發件人信息。

// 創建事件監聽器
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)
}

}

// 註冊事件監聽器
fun main(args: Array<string>) {

val springApplication = SpringApplication(StartApplication::class.java)
springApplication.addListeners(ApplicationStartup())
springApplication.run(*args)

}
/<string>/<contextrefreshedevent>

最後發送郵件的代碼如下

@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
}

}

文章到這裡就結束了,感謝閱讀!ths!


歡迎在留言區留下你的觀點,一起討論提高。如果今天的文章讓你有新的啟發,學習能力的提升上有新的認識,歡迎轉發分享給更多人。


猜你還想看


阿里、騰訊、百度、華為、京東最新面試題彙集

探究 Nginx 中 reload 流程的真相

Linux 中的零拷貝技術,看完這篇文章你就明白了!

HTTPS 原理分析:帶著疑問層層深入


關注「程序員小樂」,收看更多精彩內容
嘿,你在看嗎?



分享到:


相關文章: