前往小程序,Get更优阅读体验!
立即前往
首页
学习
活动
专区
工具
TVP
发布
社区首页 >专栏 >Spring Boot 执行定时任务

Spring Boot 执行定时任务

作者头像
每天学Java
发布2020-06-02 09:51:26
6140
发布2020-06-02 09:51:26
举报
文章被收录于专栏:每天学Java每天学Java每天学Java

Spring Boot中可以使用注解实现定时任务,十分方便。今天的文章我们首先讲一下个人的项目,然后在文章后面我们将定时任务与线程池结合起来实现每天的个人支出的计算。

最近在学习Spring Security的时候顺便想给自己做一个资产管理的系统,出于学习的目的很多东西都没做好,只做了一个新增支出的功能。使用到的框架有Spring Boot,Spring Security,Mybatis。数据库使用的是sqlserver(Mac安装SqlServer需要Docker实现,大家可以学习一下Docker)。

那我们步入正题。

01

使用支付宝的记账本,不能让我知道我每天支出多少,因为我大多数懒得去看,我就想通过自己记账的动作来让自己逐渐养成理财的习惯。既然是资金管理那么首先我们就要记录支出了(关于登录我就不再多说了前面Spring Security的文章中讲到登录的安全访问,Spring Security项目地址:https://github.com/xynuSuMu/SpringSecurity.git):

在这里我们可以一笔一笔的记录自己每天支出。同时我自己也记录了6号到10号的支出明细,然后现在就有一个问题了,每天有好多笔支出,我想知道每天支出到底多少钱,此时我就想到定时器了。在Spring Boot中使用定时器的方式有好几种方式,我这里选择最快捷的注解方式(如下代码)。

Component我想大家很熟悉,组件的意思。被此注解修饰的类会实例化到Spring容器中,这里如何不写这个注解定时任务不会被触发。EnableScheduling提供了快速的基于多种规则的任务调度功能。Scheduled就是配合EnableScheduling快速开启任务调度功能。所以我们在一个自定义的类中,添加这三个注解就实现定时器的实现。

@Component
@EnableScheduling
public class Scheduling {

    @Autowired
    private PayService payService;
    @Scheduled(cron = "0 */1 * * * ?")
    private void countMoney() {
        FundThreadPool.singleton.getFixedInstance().submit(new Runnable() {
            @Override
            public void run() {
                System.out.println(payService.countMoney());
            }
        });
    }
}

FundThreadPool是一个枚举类,负责提供一个单例的线程池类。ExecutorService

Java通过Executors提供四种线程池,分别为:

newCachedThreadPool创建一个可缓存线程池,如果线程池长度超过处理需要,可灵活回收空闲线程,若无可回收,则新建线程。 newFixedThreadPool 创建一个定长线程池,可控制线程最大并发数,超出的线程会在队列中等待。 newScheduledThreadPool 创建一个定长线程池,支持定时及周期性任务执行。 newSingleThreadExecutor 创建一个单线程化的线程池,它只会用唯一的工作线程来执行任务,保证所有任务按照指定顺序(FIFO, LIFO, 优先级)执行。

这里我使用定长的线程池。上面四种线程池实际上还是执行ThreadPoolExecutor的构造器,只不过参数不同。

public enum FundThreadPool {
    singleton;
    private ExecutorService executorService;
    private Logger logger = LoggerFactory.getLogger(FundThreadPool.class);

    FundThreadPool() {
        logger.info("调用线程池");
//        定长线程池,可控制线程最大并发数,超出的线程会在队列中等待。
        executorService = Executors.newFixedThreadPool(3);

    }

    public ExecutorService getFixedInstance() {
        return executorService;
    }
}

现在我们实现了定时器结合线程池获取前一天的开销,那么这个开销是怎么去计算的呢?我这里通过SQL语句去实现的,这里DATEDIFF函数用于SQL Server中,和MySQL中的函数是有区别的,MySQL 中DATEDIFF函数只有两个日期参数,返回两个日期之间的天数。SQL Server中可以指定类型。getDate()是获取当前的日期,date是数据库你设计的日期字段,=1表明查询昨天的数据。

    <select id="countMoney" resultType="java.lang.Integer">
        SELECT sum (money) as money 
        from payInfo 
        where 
        DATEDIFF(DD,date,getDate())=1;
    </select>
本文参与 腾讯云自媒体分享计划,分享自微信公众号。
原始发表:2018-11-11,如有侵权请联系 cloudcommunity@tencent.com 删除

本文分享自 每天学Java 微信公众号,前往查看

如有侵权,请联系 cloudcommunity@tencent.com 删除。

本文参与 腾讯云自媒体分享计划  ,欢迎热爱写作的你一起参与!

评论
登录后参与评论
0 条评论
热度
最新
推荐阅读
相关产品与服务
云数据库 MySQL
腾讯云数据库 MySQL(TencentDB for MySQL)为用户提供安全可靠,性能卓越、易于维护的企业级云数据库服务。其具备6大企业级特性,包括企业级定制内核、企业级高可用、企业级高可靠、企业级安全、企业级扩展以及企业级智能运维。通过使用腾讯云数据库 MySQL,可实现分钟级别的数据库部署、弹性扩展以及全自动化的运维管理,不仅经济实惠,而且稳定可靠,易于运维。
领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档