SpringBoot利用线程池实现异步发送邮件

SpringBoot利用线程池实现异步发送邮件

一.前言

1.什么异步

说到什么是异步就要先了解一下和他相对的同步,同步就是指一个接口在调用某个方法的时候,若该方法需要一段时间才能返回信息,那么这个接口会一直的等下去,直到该方法返回信息才能处理下面的逻辑;异步的话就不用等待该方法返回信息,就可以继续处理该接口下面的逻辑。
在这里举个注册发送邮件的例子:

  • 同步:
    在这里插入图片描述
  • 异步:
    在这里插入图片描述

2.使用场景

使用到异步的场景可谓是数不胜数,就比如:

  1. 注册发送邮件,发送短信
  2. 定时批处理(比如数据同步)
  3. 微信消息通知

二.代码实现

1.整合线程池

整合线程池可以参考SpringBoot整合线程池

2.整合邮箱及其工具类

整合邮箱及其工具类可以参考SpringBoot整合邮箱

3.实体类

package com.temperature.humidity.system.entity;

import lombok.Data;

/**
 * 账户
 */
@Data
public class UserInfo {

    /**
     * 用户账号
     */
    private String username;

    /**
     * 用户密码
     */
    private String password;

    /**
     * 用户邮箱
     */
    private String email;

}

4.Controller层

package com.temperature.humidity.system.controller;

import com.temperature.humidity.system.common.utils.OurMailUtil;
import com.temperature.humidity.system.entity.UserInfo;
import lombok.extern.log4j.Log4j2;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.web.bind.annotation.PostMapping;
import org.springframework.web.bind.annotation.RequestBody;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RestController;

import javax.mail.MessagingException;
import java.util.LinkedHashMap;
import java.util.Map;
import java.util.concurrent.Executor;

@RestController
@RequestMapping("/email")
@Log4j2
public class EmailTestController {

    /**
     * 用于存储用户的信息
     * 该Map的key为用户账号,value为用户信息
     */
    private static final Map<String, UserInfo> userInfoMap = new LinkedHashMap<>();

    /**
     * 将mail工具类注入进来
     */
    @Autowired
    private OurMailUtil ourMailUtil;

    /**
     * 将线程池注入进来
     */
    @Autowired
    private Executor threadPoolTaskExecutor;

    @PostMapping("/sent")
    public String sentEmail(@RequestBody UserInfo userInfo) {
        long startTime = System.currentTimeMillis();
        try {
            //注册用户
            userInfoMap.put(userInfo.getUsername(), userInfo);
            //要发送人的邮箱
            String toEmail = userInfo.getEmail();
            //邮箱主题
            String subject = "邮箱测试-html";
            //邮箱内容
            String text = "<p style='color:red'>我是红色</p>";
            threadPoolTaskExecutor.execute(() -> {
                try {
                    //调用发送邮件方法
                    ourMailUtil.sendMailForOnePeople(toEmail, subject, text);
                    long emailEndTime = System.currentTimeMillis();
                    log.info("线程{}执行完成,用时{}", Thread.currentThread().getName(), emailEndTime - startTime);
                } catch (MessagingException e) {
                    throw new RuntimeException(e);
                }
            });
            long endTime = System.currentTimeMillis();
            log.info("线程{}执行完成,用时{}", Thread.currentThread().getName(), endTime - startTime);
            return "用户" + userInfoMap.get(userInfo.getUsername()) + "注册成功";
        } catch (RuntimeException e) {
            return "注册失败!";
        }
    }

}

三.测试

我们用Postman传入相应参数发送请求后,返回的结果(出参)如我们所愿。
在这里插入图片描述
并且通过下图我们不仅可以看出执行发送邮箱方法的线程并不是主线程而是从线程池中拿的,而且可以通过主线程用时1,而发送邮箱的线程用时3839可以看出我们的发送邮箱方法是异步执行的。
在这里插入图片描述

  • 1
    点赞
  • 8
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值