Spring Boot定时发送短信的两种方式

不少项目中估计都有遇到定时发送这个梗,我也遇到了,页面中下拉框选项有立即发送以及定时发送,立即发送就不用说了,定时发送可以讲一下,定时的方式有很多种,Java自带的定时器,Spring的定时器,大致讲一下我做的时候思路

1. Java自带的定时器

java.util包里的Timer,它也可以实现定时任务但是功能过于单一所有使用很少,而还有一个类ScheduledExecutorService可以基本满足定时任务中的需求

首先要创建一个线程,这里实现了Runnable接口,自己写run方法

public class MessageJob implements Runnable {private static final Logger LOGGER = LoggerFactory.getLogger(MessageJob.class);private static volatile ConcurrentHashMap<String, String> idMapping = new ConcurrentHashMap<>();private static volatile ConcurrentHashMap<String, MessageJob> cache = new ConcurrentHashMap<>();private volatile AtomicBoolean canceled = new AtomicBoolean(false);/** 任务id */private String jobId;/** 短信id */private String messageId;private UserDTO userDTO;private String title;private String context;private String phone;public MessageJob(String messageId, UserDTO UserDTO, String title, String context, String phone) {this.jobId = GeneratorIDFactory.generatorUUID();this.messageId = messageId;this.userDTO = UserDTO;this.title = title;this.context = context;this.phone = phone;//取消并清除上一次任务cancelAndClearLastJobIfExist();//缓存本次任务cacheThisJob();}/*** 取消并清除上一次任务*/private void cancelAndClearLastJobIfExist() {if (StringUtil.isNotEmpty(idMapping.get(messageId))) {MessageJob lastJob = cache.get(idMapping.get(messageId));if (null != lastJob) {lastJob.cancelJob();cache.remove(idMapping.get(messageId));idMapping.remove(messageId);}}}@Overridepublic void run() {//判断任务是否被取消if (!canceled.get()) {SendMessageUtil sendMessageUtil = (SendMessageUtil) SpringContextUtil.getBean("sendMessageUtil");MsgMessageService msgMessageService = (MsgMessageService) SpringContextUtil.getBean("msgMessageService");//发送try {sendMessageUtil.sendMessage(userDTO, title, context, phone);LOGGER.info("线程已启动");MsgMessage message = new MsgMessage();message.setState(1);message.setId(messageId);msgMessageService.update(message);LOGGER.info("短信状态已更新");} catch (ServiceException e) {LOGGER.error("线程出现问题::" + e.getMessage(), e);}//从缓存中清理本任务clear();}}/*** 缓存本次任务*/private void cacheThisJob() {//id映射idMapping.put(this.messageId, this.jobId);//短信发送任务缓存cache.put(this.jobId, this);}/*** 取消任务*/public void cancelJob() {this.canceled.set(true);}/*** 清理缓存*/public void clear() {idMapping.remove(messageId);cache.remove(this.jobId);}}

模拟了缓存,以及队列,jobId是UUID自动生成,防止ID重复,一个短信ID对应一个jobId,一个jobId对应一个线程的方式,确保线程分布执行,不干扰

这么做的意义在于,可在定时发送日期还没到时取消发送短信,一个短信发送时间经过编辑后可清空上一次任务新建一个线程,调用代码如下

ScheduledExecutorService service = new ScheduledThreadPoolExecutor(10, new BasicThreadFactory.Builder().namingPattern("scheduled-pool-%d").daemon(true).build());
MessageJob job = new MessageJob(msgMessage.getId(), sender, "短信通知", messagecontent, phones);
long delay = msgMessage.getSendertime().getTime() - System.currentTimeMillis();
service.schedule(job, delay, TimeUnit.MILLISECONDS);

delay是短信发送的时间减去当前时间的毫秒,让定时器在规定时间后执行这个线程发送短信

2. Spring的定时器注解

Spring Boot定时器就不介绍了,也很方便简单,在启动类上加上注解@EnableScheduling就可以了

这种方式比较适用于在项目中,短信的所有信息都存在数据里里的情况下,根据type来区分是定时发送还是立即发送,state来区别是已发送还是未发送;这个定时器只需要读取出所有状态是未发送并且是定时发送的数据库数据,并且发送时间是小于当前时间的

select * from message where type = 2 and state = 2 and send_time <= now();

举例,有一条短信是2019-1-17 22:05:00要发送的,定时任务一直在开启,到17号22点05分00秒的时候的时候这个now()就是当前时间,<=正好查到这条数据,那就表示到了该发送的时间,将短信发送出去

@Component
public class MessageJobTwo {private static final Logger logger = LoggerFactory.getLogger(MessageJobTwo.class);@Autowiredprivate MsgMessageMapper messageMapper;@Autowiredprivate MsgMessagemapperService msgMessagemapperService;@Autowiredprivate SendMessageUtil sendMessageUtil;@Value("${message.isopen}")private boolean isOpen;/*** 每隔两秒定时查询小于等于当前时间的并且为未发送定时的数据* 对数据进行发送并且更改短信状态*/@Scheduled(cron = "*/2 * * * * ?")public void sendMessageJob(){if (isOpen) {logger.info("开始执行-----短信定时任务");MsgMessageDTO msgMessageDTO = new MsgMessageDTO();msgMessageDTO.setType(2);msgMessageDTO.setState(2);msgMessageDTO.setSendertime(new Date());Map<String, Object> params = new HashMap<>(16);params.put("condition", msgMessageDTO);List<MsgMessageDTO> messageList = messageMapper.messageList(params);for (MsgMessageDTO messageDTO : messageList) {String phones = selectPhone(messageDTO.getId());sendMessageUtil.sendMessage(null, "短信通知", messageDTO.getMessagecontent(), phones);logger.info("短信发送成功---------");MsgMessage message = new MsgMessage();message.setState(1);message.setId(messageDTO.getId());messageMapper.update(message);logger.info("短信状态修改完成---------");}}}/*** 查询接收用户,拼接成字符串* @param messageId* @return*/private String selectPhone(String messageId){Condition condition = new Condition(MsgMessagemapper.class);condition.createCriteria().andEqualTo("messageid", messageId);List<MsgMessagemapper> byCondition = msgMessagemapperService.findByCondition(condition);StringBuilder builder = new StringBuilder();for (MsgMessagemapper msgMessagemapper : byCondition) {builder.append(msgMessagemapper.getReceivephone()).append(",");}builder.deleteCharAt(builder.length() - 1);return builder.toString();}
}

结语

第二种方式比较方便,是不需要调用,项目启动之后会根据cron表达式里的时间进行操作,定时在查询,查出有符合要求的数据就进行发送。

第一种方式也可以,是异步多线程,第二种是单线程,看需求选择。

Spring Boot定时发送短信相关推荐

  1. 延迟发送:4款定时发送短信的应用程序

    发送短信已经成为朋友.家人甚至是同事之间最为常见的通讯方式之一.由于短信具备定时发送及发送报告等功能,使用起来非常灵活.当然,短信的应用程序中常常默认带有发送报告功能,而没有定时发送的功能,若是能具备 ...

  2. MTK 7.1 定时发送短信功能

    此功能的主要设计思路是: 在短信添加附件的list列表中添加一个定时发送短信的选项,用户可以通过添加定时短信来设置短信要发送出去的时间,定时短信发送出去后,后台定时器会根据用户设置的时间进行定时判定, ...

  3. 阿里云API定时发送短信(小记)

    定时任务的代码:import com.google.gson.Gson; import com.jianke.bid.common.SMSUtils; import org.springframewo ...

  4. thinkphp6对接阿里云短信服务完成定时发送短信功能

    1.导入阿里短信包 通过composer下载依赖包 composer require alibabacloud/dysmsapi-20170525 2.0.22 具体可参见阿里云短信服务 >&g ...

  5. python邮件定时发送短信_Python趣味编程:如何定时发短信给Ta讲笑话

    原标题:Python趣味编程:如何定时发短信给Ta讲笑话 人一无聊,就会想:反正每天都要给Ta问候一声早安,为何不同时讲个笑话呢?如果能写个程序每天早上定时给Ta发一条问候早安同时讲一个笑话的短信该多 ...

  6. springboot定时发送短信_SpringBoot第十七篇:定时任务

    引言 相信大家对定时任务很熟悉,其重要性也不言而喻.定时发短信.定时批量操作.定时统计数据等,都离不开定时任务.本文将讲解定时任务在 SpringBoot 项目中的应用. 版本信息 JDK:1.8 S ...

  7. quartz-job实现实时或定时发送短信任务

    存放调度器(Job 和 Trigger)信息的xml配置文件: 这是某个指定的要实现的定时任务: <!-- 每天给项目经理发送短信避免短信服务挂了 定时每天08:30执行--> <j ...

  8. php定时发送短信,php发送短信代码

    /*-------------------------------- 功能:  HTTP接口 发送短信 修改日期: 2011-03-04 说明:  http://api.sms.cn/mt/?uid= ...

  9. python邮件定时发送短信_python实现自动定时给女朋友发手机短信,每天一个笑话!...

    加小编QQ群:832339352 即可自动获取大量Python视频教程以及各类PDF! 大四的生活就是这么无聊,我琢磨着也学了这么多东西了,为啥不能用自己的知识来给生活找点乐子呢?我想反正每天都要给T ...

最新文章

  1. Jquery Ajax时 error处理 之 parsererror
  2. Linux(Centos7)下redis5安装、部署、开机自启
  3. AndroidAnnotations框架简单使用方法
  4. JVM调优总结(五)-分代垃圾回收详述1
  5. javascript实现yield
  6. 阿里云短信官方的java示例是错误的
  7. 播放提示音+页面右下角提示框
  8. C# Json转对象
  9. 企业微信_读取成员(获取用户详情)
  10. ERP系统重新打开订单的后台限制解析
  11. mysql二进制日志管理
  12. 2022.8.16-8.18深圳核芯物联作为唯一的蓝牙AOA定位基站厂家受邀参加第十届中国电子信息博览会
  13. mt管理器怎么运行HTML文件,MT管理器怎么修改游戏数据 MT管理器修改内购教程
  14. PDF Expert永久版
  15. hellow world
  16. 【整蛊系列大合集】整蛊又有新套路,遇到这种情况你会怎么办?看完笑死爹了。
  17. RealView编译器常用特有功能(转)
  18. Kaggle泰坦尼克号-决策树Top 3%-0基础代码详解
  19. matlab输出多个参数到表格固定列,matlab将excle的列提取出来?如何使用Matlab提取Excel中指定列的数据?...
  20. samba服务器介绍

热门文章

  1. Java.Net虚拟机精简(GreenJVMGreenDotNet发布)
  2. 5g无线图传信号测试软件,5GWIFI信号和2.4GWFI信号有什么区别?
  3. html给图片各区域加功能(img usemap)
  4. 学习OpenCV(6) EmguCV 双目视觉
  5. 机械原理笔记(一)构件、运动副、运动链与机构
  6. matplotlib添加字体及中文乱码问题
  7. 荧光性能的CdTe/CdS核壳量子点 CdTe/CdS core-shell QDs
  8. 【已解决】win10禁止更新-服务、组策略两步解决
  9. 【RuoYi优化】调整JVM启动内存
  10. VK1650 LED数码显示驱动IC