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!