SpringBoot 动态配置邮箱发件人

点击上方 "程序员小乐"关注, 星标或置顶一起成长

每天凌晨00点00分, 第一时间与你相约

每日英文

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

程序员小乐(ID:study_tech)第 723 次推文   图片来自网络

往日回顾:关于如何挣钱的35条建议!万字长文

   正文   

现在的消息模块少不了邮件发送、短信发送和手机推送的功能。邮件发送的功能历史最为悠久,也算的上烂大街的功能。一般在配置文件中设置好邮箱地址、账号、密码和发件服务器地址后便不会再去改动。可是有的客户却希望人为指定发件人信息。这个需求并不过分,需要解决两个大问题:如何在容器启动成功后重新修改发送邮件的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!

欢迎在留言区留下你的观点,一起讨论提高。如果今天的文章让你有新的启发,学习能力的提升上有新的认识,欢迎转发分享给更多人。

欢迎各位读者加入程序员小乐技术群,在公众号后台回复“加群”或者“学习”即可。

猜你还想看

阿里、腾讯、百度、华为、京东最新面试题汇集

探究 Nginx 中 reload 流程的真相

Linux 中的零拷贝技术,看完这篇文章你就明白了!

HTTPS 原理分析:带着疑问层层深入

关注「程序员小乐」,收看更多精彩内容

嘿,你在看吗

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值