SpringBoot 動態配置郵箱發件人java
如今的消息模塊少不了郵件發送、短信發送和手機推送的功能。郵件發送的功能歷史最爲悠久,也算的上爛大街的功能。通常在配置文件中設置好郵箱地址、帳號、密碼和發件服務器地址後便不會再去改動。但是有的客戶卻但願人爲指定發件人信息。這個需求並不過度,須要解決兩個大問題:如何在容器啓動成功後從新修改發送郵件的Bean。如何在服務器重啓後,發件人依然是更改後的配置信息。這裏記錄實現的步驟。spring
一)、在未配置郵箱帳號時,系統擁有默認的郵箱發件人服務器
二)、從新設置郵箱發件人後,需當即生效app
三)、重啓服務器後,郵箱發件人依然是更改後的郵箱帳號,而非默認發件人socket
郵箱發送的功能放在如今變得很是的簡單好用,一導二配三發送。😊ide
第一步:導入郵箱依賴包spring-boot
compile('org.springframework.boot:spring-boot-starter-mail')
第二步:配置發件人郵箱信息post
spring: mail: host: smtp.mxhichina.com username: itdragon@xx password: itdragon default-encoding: utf-8
第三步:發送郵件this
@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內存的角度看,這樣作彷佛沒毛病!若是有不對的地方望不吝賜教😋.net
@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!