SpringBoot 動態(tài)配置郵箱發(fā)件人過程解析
前言
現(xiàn)在的消息模塊少不了郵件發(fā)送、短信發(fā)送和手機(jī)推送的功能。郵件發(fā)送的功能歷史最為悠久,也算的上爛大街的功能。一般在配置文件中設(shè)置好郵箱地址、賬號、密碼和發(fā)件服務(wù)器地址后便不會再去改動??墒怯械目蛻魠s希望人為指定發(fā)件人信息。這個需求并不過分,需要解決兩個大問題:如何在容器啟動成功后重新修改發(fā)送郵件的Bean。如何在服務(wù)器重啟后,發(fā)件人依然是更改后的配置信息。這里記錄實(shí)現(xiàn)的步驟。
需求分析
一)、在未配置郵箱賬號時,系統(tǒng)擁有默認(rèn)的郵箱發(fā)件人
二)、重新設(shè)置郵箱發(fā)件人后,需立即生效
三)、重啟服務(wù)器后,郵箱發(fā)件人依然是更改后的郵箱賬號,而非默認(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ā)件人。首先我們要解決第一個問題,JavaMailSender 的Bean對象是在容器啟動成功后就已經(jī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 }
再來解決第二個問題,服務(wù)器重啟后,默認(rèn)情況下依然會重新加載application.yml中的配置信息。這會出現(xiàn)郵箱發(fā)件人和實(shí)際配置的發(fā)件人不匹配的情況。其實(shí)這個問題也很好解決,加一個事件監(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源碼解析之Gateway請求轉(zhuǎn)發(fā)
今天給大家?guī)淼氖顷P(guān)于Java的相關(guān)知識,文章圍繞著Gateway請求轉(zhuǎn)發(fā)展開,文中有非常詳細(xì)介紹及代碼示例,需要的朋友可以參考下2021-06-06教你用Java實(shí)現(xiàn)RSA非對稱加密算法
今天帶各位小伙伴學(xué)習(xí)怎么用Java實(shí)現(xiàn)RSA非對稱加密算法,文中有非常詳細(xì)的解釋及代碼示例,對正在學(xué)java算法的小伙伴們很有幫助,需要的朋友可以參考下2021-05-05一場由Java中Integer引發(fā)的踩坑實(shí)戰(zhàn)
Java中的數(shù)據(jù)類型分為基本數(shù)據(jù)類型和復(fù)雜數(shù)據(jù)類型int是前者而integer是后者(也就是一個類),下面這篇文章主要給大家介紹了關(guān)于由Java中Integer引發(fā)的踩坑實(shí)戰(zhàn),需要的朋友可以參考下2022-11-11Jmeter參數(shù)化獲取序列數(shù)據(jù)實(shí)現(xiàn)過程
這篇文章主要介紹了Jmeter參數(shù)化獲取序列數(shù)據(jù)實(shí)現(xiàn)過程,文中通過示例代碼介紹的非常詳細(xì),對大家的學(xué)習(xí)或者工作具有一定的參考學(xué)習(xí)價值,需要的朋友可以參考下2020-07-07struts2中通過json傳值解決亂碼問題的實(shí)現(xiàn)方法
這篇文章主要介紹了struts2中通過json傳值解決亂碼問題的實(shí)現(xiàn)方法,涉及js編碼及java解碼的相關(guān)操作技巧,需要的朋友可以參考下2016-06-06springboot啟動前執(zhí)行方法的四種方式總結(jié)
這篇文章主要給大家介紹了關(guān)于springboot啟動前執(zhí)行方法的四種方式,文中通過實(shí)例代碼介紹的非常詳細(xì),對大家的學(xué)習(xí)或者工作具有一定的參考學(xué)習(xí)價值,需要的朋友可以參考下2022-01-01Java日常練習(xí)題,每天進(jìn)步一點(diǎn)點(diǎn)(47)
下面小編就為大家?guī)硪黄狫ava基礎(chǔ)的幾道練習(xí)題(分享)。小編覺得挺不錯的,現(xiàn)在就分享給大家,也給大家做個參考。一起跟隨小編過來看看吧,希望可以幫到你2021-08-08