SpringBoot 動態配置郵箱發件人
- 2019 年 10 月 3 日
- 筆記
SpringBoot 動態配置郵箱發件人
現在的消息模組少不了郵件發送、簡訊發送和手機推送的功能。郵件發送的功能歷史最為悠久,也算的上爛大街的功能。一般在配置文件中設置好郵箱地址、帳號、密碼和發件伺服器地址後便不會再去改動。可是有的客戶卻希望人為指定發件人資訊。這個需求並不過分,需要解決兩個大問題:如何在容器啟動成功後重新修改發送郵件的Bean。如何在伺服器重啟後,發件人依然是更改後的配置資訊。這裡記錄實現的步驟。
需求分析
一)、在未配置郵箱帳號時,系統擁有默認的郵箱發件人
二)、重新設置郵箱發件人後,需立即生效
三)、重啟伺服器後,郵箱發件人依然是更改後的郵箱帳號,而非默認發件人
基礎的郵箱發送
郵箱發送的功能放在現在變得非常的簡單好用,一導二配三發送。?
第一步:導入郵箱依賴包
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) }
最後發送郵件的程式碼如下
@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!