【Spring Boot 2.0学习之旅-10】SpringBoot整合定时任务和异步任务处理

2023-05-16

第十章 SpringBoot整合定时任务和异步任务处理

10-1 SpringBoot定时任务schedule讲解

1.定时器比较

什么是定时任务,使用场景 ?

比如八月十五,定时任务会轮询,加载到任务区里面,去检测

比如电商系统,下单量、访客、交易量,用于数据分析

  • 某个时间定时处理某个任务
  • 发邮件、短信等
  • 消息提醒
  • 订单通知
  • 统计报表系统

常见定时任务

  • Java自带的java.util.Timer类配置比较麻烦,时间延后问题,有些BUG
  • Quartz框架: 配置更简单,xml或者注解适合分布式或者大型调度作业,功能很强大
  • SpringBoot框架自带,很便捷

定时器比较

框架名称Cron表达式固定间隔执行固定频率执行任务持久化难易度
TimerTask不支持支持支持不支持一般
schedule支持支持支持不支持简单
Quartz支持支持支持支持

在实际应用中,如果没有分布式场景(quartz 支持分布式, schedule 不支持(需要自己实现,用分布式锁),schedule跟spring结合的更好,还是很适用的。

2.SpringBoot使用注解方式开启定时器

  • 启动类里面 @EnableScheduling开启定时任务,自动扫描
  • 定时任务业务类 加注解 @Component被容器扫描
  • 定时执行的方法加上注解 @Scheduled(fixedRate=2000) 定期执行一次

启动类

package com.lcz.spring_demo16;

import org.springframework.boot.SpringApplication;
import org.springframework.boot.autoconfigure.SpringBootApplication;
import org.springframework.scheduling.annotation.EnableScheduling;

@SpringBootApplication
@EnableScheduling
public class SpringDemo16Application {

    public static void main(String[] args) {
        SpringApplication.run(SpringDemo16Application.class, args);
    }

}

任务类

package com.lcz.spring_demo16.controller;

import org.springframework.scheduling.annotation.Scheduled;
import org.springframework.stereotype.Component;

import java.util.Date;

/**
 * @author : codingchao
 * @date : 2021-11-26 09:52
 * @Description:
 **/
@Component
public class ScheduledController {
    @Scheduled(fixedRate = 2000)
    public void printDate(){
        System.out.println(new Date());
    }
}

在这里插入图片描述

小结

	1、常见定时任务 Java自带的java.util.Timer类
		timer:配置比较麻烦,时间延后问题
		timertask:不推荐

	2、Quartz框架
		配置更简单
		xml或者注解

	3、SpringBoot使用注解方式开启定时任务
		1)启动类里面 @EnableScheduling开启定时任务,自动扫描
		2)定时任务业务类 加注解 @Component被容器扫描
		3)定时执行的方法加上注解 @Scheduled(fixedRate=2000) 定期执行一次

10-2 SpringBoot常用定时任务配置实战

1.cron详细说明

cron一共有7位,但是最后一位是年,可以留空,所以我们可以写6位:

  • 第一位,表示秒,取值0-59

  • 第二位,表示分,取值0-59

  • 第三位,表示小时,取值0-23

  • 第四位,日期天/日,取值1-31

  • 第五位,日期月份,取值1-12

  • 第六位,星期,取值1-7,星期一,星期二…,注:不是第1周,第二周的意思 另外:1表示星期天,2表示星期一。

  • 第七位,年份,可以留空,取值1970-2099

cron中,还有一些特殊的符号,含义如下:

(*)星号:可以理解为每的意思,每秒,每分,每天,每月,每年...
(?)问号:问号只能出现在日期和星期这两个位置,表示这个位置的值不确定,每天3点执行,所以第六位星期的位置,我们是不需要关注的,就是不确定的值。同时:日期和星期是两个相互排斥的元素,通过问号来表明不指定值。比如,1月10日,比如是星期1,如果在星期的位置是另指定星期二,就前后冲突矛盾了。
(-)减号:表达一个范围,如在小时字段中使用“10-12”,则表示从10到12点,即10,11,12
(,)逗号:表达一个列表值,如在星期字段中使用“1,2,4”,则表示星期一,星期二,星期四
(/)斜杠:如:x/y,x是开始值,y是步长,比如在第一位(秒) 0/15就是,从0秒开始,每15秒,最后就是0,15,30,45,60    另:*/y,等同于0/y

常见cron表达式

0 0 10,14,16 * * ? 每天上午10点,下午2点,4点 
0 0/30 9-17 * * ? 朝九晚五工作时间内每半小时 
0 0 12 ? * WED 表示每个星期三中午12点 
"0 0 12 * * ?" 每天中午12点触发 
"0 15 10 ? * *" 每天上午10:15触发 
"0 15 10 * * ?" 每天上午10:15触发 
"0 15 10 * * ? *" 每天上午10:15触发 
"0 15 10 * * ? 2005" 2005年的每天上午10:15触发 
"0 * 14 * * ?" 在每天下午2点到下午2:59期间的每1分钟触发 
"0 0/5 14 * * ?" 在每天下午2点到下午2:55期间的每5分钟触发 
"0 0/5 14,18 * * ?" 在每天下午2点到2:55期间和下午6点到6:55期间的每5分钟触发 
"0 0-5 14 * * ?" 在每天下午2点到下午2:05期间的每1分钟触发 
"0 10,44 14 ? 3 WED" 每年三月的星期三的下午2:10和2:44触发 
"0 15 10 ? * MON-FRI" 周一至周五的上午10:15触发 
"0 15 10 15 * ?" 每月15日上午10:15触发 
"0 15 10 L * ?" 每月最后一日的上午10:15触发 
"0 15 10 ? * 6L" 每月的最后一个星期五上午10:15触发 
"0 15 10 ? * 6L 2002-2005" 2002年至2005年的每月的最后一个星期五上午10:15触发 
"0 15 10 ? * 6#3" 每月的第三个星期五上午10:15触发

2.crontab工具

官网

在这里插入图片描述

在这里插入图片描述

  • fixedRate: 定时多久执行一次(从上一次开始执行时间点后xx秒再次执行;)
  • fixedDelay: 上一次执行结束时间点后xx秒再次执行。就是等任务结束之后才去执行。

不同场景

  • 如果每调度一次,下次不管有没有结束都统计,就是用fixedRate

  • 如果调度需要等任务结束,再去执行,就用fixedDelay。相当于总耗时,任务耗时加定时耗时

小结:

简介:SpringBoot常用定时任务表达式配置和在线生成器

	1、cron 定时任务表达式 @Scheduled(cron="*/1 * * * * *") 表示每秒
		1)crontab 工具  https://tool.lu/crontab/
	2、fixedRate: 定时多久执行一次(上一次开始执行时间点后xx秒再次执行;)
	3、fixedDelay: 上一次执行结束时间点后xx秒再次执行
	4、fixedDelayString:  字符串形式,可以通过配置文件指定

10-3 SpringBoot2.x异步任务实战

1.异步任务

有时接收到客户端请求后,在后台分发多个任务异步执行,而主线程先对客户端进行响应以提高用户体验。这时就涉及到了异步任务的调用。

设想一个场景:用户请求支付订单,这时应快速响应订单支付提交,而后台需要异步开启用户积分增加、减少商品库存、检测薅羊毛等一系列任务。

  1. 创建异步任务业务类如 MyAsyncTask并添加 @Component注解。

  2. 在需要被异步调用的方法上添加 @Async注解

异步任务MyAsyncTask

package com.lcz.spring_demo16.task;

import org.springframework.scheduling.annotation.Async;
import org.springframework.stereotype.Component;

/**
 * @author : codingchao
 * @date : 2021-11-26 10:52
 * @Description:
 **/
@Component
public class MyAsyncTask {
    @Async
    public void task1() {
        long begin = System.currentTimeMillis();
        //模拟增加用户积分
        try {
            Thread.sleep(1000);
        } catch (InterruptedException e) {
            e.printStackTrace();
        }
        long end = System.currentTimeMillis();
        System.out.println("task1 spent:"+(end-begin));
    }

    @Async
    public void task2() {
        long begin = System.currentTimeMillis();
        //模拟减少商品库存
        try {
            Thread.sleep(2000);
        } catch (InterruptedException e) {
            e.printStackTrace();
        }
        long end = System.currentTimeMillis();
        System.out.println("task2 spent:"+(end-begin));
    }

    @Async
    public void task3() {
        long begin = System.currentTimeMillis();
        //检测薅羊毛
        try {
            Thread.sleep(3000);
        } catch (InterruptedException e) {
            e.printStackTrace();
        }
        long end = System.currentTimeMillis();
        System.out.println("task3 spent:"+(end-begin));
    }

}

启动类

在启动类上添加 @EnableAsync注解以使组件中的 @Async注解生效

异步测试执行

package com.lcz.spring_demo16.controller;

import com.lcz.spring_demo16.task.MyAsyncTask;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RestController;

/**
 * @author : codingchao
 * @date : 2021-11-26 10:55
 * @Description:
 **/
@RestController
public class AsyncController {
    @Autowired
    private MyAsyncTask myAsyncTask;

    @RequestMapping("submit")
    public String submitOrder() {
        System.out.println("用户请求支付订单===========");
        long begin = System.currentTimeMillis();
        myAsyncTask.task1();
        myAsyncTask.task2();
        myAsyncTask.task3();
        long end = System.currentTimeMillis();
        System.out.println("订单提交成功=====耗时:" + (end - begin));
        return "success";
    }

}

输出结果:

在这里插入图片描述

2.Future

如果你想在异步执行一系列任务并获取任务执行结果后再响应该怎么办?JDK并发包为我们提供了 Future模式,实现了在主线程通过一个变量监控异步线程的执行状态从而在其执行完毕时获取执行结果。

  1. 在异步任务执行完后返回一个 AyncResult实例,用你想返回的数据构造该实例
package com.lcz.spring_demo16.task;

import org.springframework.scheduling.annotation.Async;
import org.springframework.scheduling.annotation.AsyncResult;
import org.springframework.stereotype.Component;

import java.util.concurrent.Future;

/**
 * @author : codingchao
 * @date : 2021-11-26 10:52
 * @Description:
 **/
@Component
public class MyAsyncTask {
    @Async
    public void task1() {
        long begin = System.currentTimeMillis();
        //模拟增加用户积分
        try {
            Thread.sleep(1000);
        } catch (InterruptedException e) {
            e.printStackTrace();
        }
        long end = System.currentTimeMillis();
        System.out.println("task1 spent:"+(end-begin));
    }

    @Async
    public void task2() {
        long begin = System.currentTimeMillis();
        //模拟减少商品库存
        try {
            Thread.sleep(2000);
        } catch (InterruptedException e) {
            e.printStackTrace();
        }
        long end = System.currentTimeMillis();
        System.out.println("task2 spent:"+(end-begin));
    }

    @Async
    public void task3() {
        long begin = System.currentTimeMillis();
        //检测薅羊毛
        try {
            Thread.sleep(3000);
        } catch (InterruptedException e) {
            e.printStackTrace();
        }
        long end = System.currentTimeMillis();
        System.out.println("task3 spent:"+(end-begin));
    }

    @Async
    public Future<String> task4(){
        long begin = System.currentTimeMillis();
        //模拟增加用户积分
        try {
            Thread.sleep(1000);
        } catch (InterruptedException e) {
            e.printStackTrace();
        }
        long end = System.currentTimeMillis();
        System.out.println("task1 spent:"+(end-begin));
        return new AsyncResult<>("task4");
    }

    @Async
    public Future<String> task5() {
        long begin = System.currentTimeMillis();
        //模拟减少商品库存
        try {
            Thread.sleep(2000);
        } catch (InterruptedException e) {
            e.printStackTrace();
        }
        long end = System.currentTimeMillis();
        System.out.println("task2 spent:"+(end-begin));
        return new AsyncResult<>("task4");
    }

    @Async
    public Future<String> task6() {
        long begin = System.currentTimeMillis();
        //检测薅羊毛
        try {
            Thread.sleep(3000);
        } catch (InterruptedException e) {
            e.printStackTrace();
        }
        long end = System.currentTimeMillis();
        System.out.println("task3 spent:"+(end-begin));
        return new AsyncResult<>("task4");
    }

}

  1. 在调用异步方法时获取异步结果变量 future,通过该变量循环判断任务执行状态 isDone并获取执行结果 get直接调用 get是阻塞的
package com.lcz.spring_demo16.controller;

import com.lcz.spring_demo16.task.MyAsyncTask;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.scheduling.annotation.Async;
import org.springframework.scheduling.annotation.AsyncResult;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RestController;

import java.util.concurrent.Future;

/**
 * @author : codingchao
 * @date : 2021-11-26 10:55
 * @Description:
 **/
@RestController
public class AsyncController {
    @Autowired
    private MyAsyncTask myAsyncTask;

    @RequestMapping("submit")
    public String submitOrder() {
        System.out.println("用户请求支付订单===========");
        long begin = System.currentTimeMillis();
        myAsyncTask.task1();
        myAsyncTask.task2();
        myAsyncTask.task3();
        long end = System.currentTimeMillis();
        System.out.println("订单提交成功=====耗时:" + (end - begin));
        return "success";
    }

    @RequestMapping("submit2")
    public String submitOrder2() {
        System.out.println("收到订单支付的请求");
        long begin = System.currentTimeMillis();
        Future<String> task4 = myAsyncTask.task4();
        Future<String> task5 = myAsyncTask.task5();
        Future<String> task6 = myAsyncTask.task6();
        while (true) {
            if (task4.isDone() && task5.isDone() && task6.isDone()) {
                long end = System.currentTimeMillis();
                System.out.println("响应耗时:"+(end-begin));
                break;
            }
        }
        return "success";
    }


}

控制台输出结果

在这里插入图片描述

小结 :

简介:讲解什么是异步任务,和使用SpringBoot2.x开发异步任务实战
	1、什么是异步任务和使用场景:适用于处理log、发送邮件、短信……等
		下单接口->查库存 100
				余额校验 150
				风控用户100
				....


	2、启动类里面使用@EnableAsync注解开启功能,自动扫描
	
	3、定义异步任务类并使用@Component标记组件被容器扫描,异步方法加上@Async
		注意点:
			1)要把异步任务封装到类里面,不能直接写到Controller
			2)增加Future<String> 返回结果 AsyncResult<String>("task执行完成");  
			3)如果需要拿到结果 需要判断全部的 task.isDone()
	4、通过注入方式,注入到controller里面,如果测试前后区别则改为同步则把Async注释掉
本文内容由网友自发贡献,版权归原作者所有,本站不承担相应法律责任。如您发现有涉嫌抄袭侵权的内容,请联系:hwhale#tublm.com(使用前将#替换为@)

【Spring Boot 2.0学习之旅-10】SpringBoot整合定时任务和异步任务处理 的相关文章

  • 【故障诊断】【git】git只能下载一个分支,怎么办?

    很多朋友可能都会遇到一个问题 xff0c 就是远程的git明明有两个分支 xff0c 但是却只能下载一个 xff0c 这样该怎么处理呢 xff1f 首先要澄清 xff0c git clone确实只能下载一个分支 xff0c 我们只能先把ma
  • 23种设计模式

    目录 创建型 1 Factory Method xff08 工厂方法 xff09 2 Abstract Factory xff08 抽象工厂 xff09 3 Builder xff08 建造者 xff09 4 Prototype xff08
  • Docker的asp.net core应用部署系列目录(完结)

    第一章 实验基础环境 本系列将用VirtualBox虚拟机安装ubuntu desktop 18 版本进行演示 xff0c 安装方式自行探索 xff0c 亦可购买各种云的linux服务器 章节间多少有依赖 xff0c 请根据自身情况跳过熟悉
  • Docker的asp.net core应用部署系列—— docker运行asp.net core应用镜像

    本系列目录请看这里 https blog csdn net michel4liu article details 80819510 我们接着上篇 xff0c 已经编译好镜像 xff0c 本篇将介绍两种启动方式 xff0c 交互模式启动和后台
  • Docker的asp.net core应用部署系列——进入正在运行的docker容器里面

    本系列目录请看这里 https blog csdn net michel4liu article details 80819510 我们之前已经可以通过交互或后台方式启动一个容器 xff0c 有时我们需要进入docker里面看一些log或者
  • DATAX:MongoDB增量数据写入到mysql中

    项目场景 xff1a 简述 xff1a 使用DATAX进行Mongo的数据抽取 xff0c 然后写入到mysql中 xff0c 其中会牵涉到全量数据的写入和增量数据的写入 全量 数据的写入我们只需要正常写JSON模板即可 xff0c 使用c
  • 无人机自动驾驶软件系列 E04

    无人机自动驾驶软件系列 E04 xff1a 深度估计 xff0c 八叉树地图以及路径规划 详细配置https gaas gitbook io guide software realization build your own autonom
  • Window11安装如何跳过TPM2.0这一步

    最近想体验一把window11 xff0c 怎奈自己的电脑太老了 xff0c 显示不能安装 xff0c 网上大佬们都说是tpm2 0的问题 xff0c 顺着这个角度 xff0c 找到了一个国外大神的解决办法 1 在出现 Win11 会提示
  • 修改已运行Docker容器的端口映射

    方法一 删除容器 xff0c 重新新建容器多加一个 p端口映射即可 方法二 修改容器配置文件 重启docker服务 模拟创建运行中的容器 span class token punctuation span root 64 redmine t
  • e指数函数

    使用win自带的计算器 xff0c 进行以e为底的指数函数进行运算时 xff0c 发现计算器上的EXP键只能用做表示10的多少次方 xff0c 如5e3 xff0c 指的是5乘以10的3次方 xff0c 及5000 查了一下 xff0c 也
  • xsens惯导在ROS下输出汇总

    rostopic list 分别记录下每个对应的信息 xff1a 1 rostopic echo diagnostics header seq 454 stamp secs 1572609754 nsecs 307622909 frame
  • c 编程中extern关键字 使用跨文件全局变量

    我们知道 xff0c 程序的编译单位是源程序文件 xff0c 一个源文件可以包含一个或若干个函数 在函数内定义的变量是局部变量 xff0c 而在函数之外定义的变量则称为外部变量 xff0c 外部变量也就是我们所讲的全局变量 它的存储方式为静
  • 年度回忆录(?——2011.01)

    这是在CSDN 上的第一篇总结 xff08 或者说是回忆录 xff09 xff0c 个人认为 xff1a 总结 xff0c 尤其是年度总结是十分必要的 她可以很好的映射出自己以往的不足 xff0c 并为自己下一步的学习指明方向 以前在网易上
  • 使用JMF实现java写自己的视频播放器

    JMF这个多媒体开发框架太牛了 xff0c 简单的几句代码就能实现一个视频播放器的开发 xff0c 厉害 xff0c 就是支持的格式少了一些 xff0c 没关系 xff0c 这个视频播放器可以播放mpg xff0c avi fvl等等 xf
  • 相机标定:关键点法 vs 直接法

    相机标定中最常见的方法是关键点法 xff0c 比如 OpenCV 和 MatLab 中使用棋盘格 圆阵列等二维图案进行标定 xff0c 这上面的棋盘格角点和圆心就是所谓的关键点 虽然关键点法有很多优点 xff0c 但在某些情况下容易遇到标定
  • 8本推荐游戏开发书籍

    很多刚刚接触游戏开发的朋友经常问我 xff1a 如何开始学习游戏开发 xff1f 我从事游戏开发行业很多年了 xff0c 坦率地讲 xff0c 开发游戏充满挑战性 xff0c 需要开发人员具备大量的技能与积极的创新精神 希望这篇小文能帮助朋
  • Maxwell启动停止脚本

    Maxwell启动停止脚本 进入 maxwell bin nbsp 直接运行下面的内容 生成脚本 bin bash description maxwell File maxwell Description Starts and stops
  • Epoll 的time_out参数引发的cpu占用问题

    转自 xff1a https www cnblogs com Jimmy104 p 5258205 html 针对自己写的一个服务器网络引擎Engine 文章后面附上源码 使用epoll 刚刚开始时候发现占用CPU 特别高 xff0c 但是
  • 【周志华机器学习】集成学习

    第八章 集成学习 个体与集成BoostingBagging 与随机森林Bagging随机森林 结合策略平均法投票法学习法 多样性 个体与集成 集成学习通过构建并结合多个学习器来完成学习任务 xff0c 也被称为多分类器系统 集成学习的一般结
  • 用户句柄表的遍历

    私有句柄表 HANDLE TABLE ENTRY的Object直接指向 OBJECT HEADER不用减 span class token macro property span class token directive hash spa

随机推荐

  • 树莓派安装后--安装必要软件(个人版)

    树莓派安装后 安装必要软件 xff08 个人版 xff09 查看是哪个版本 lsb release a 查看raspbian是哪个版本 getconf LONG BIT 查看系统位数 uname a kernel 版本 opt vc bin
  • 固定翼姿态控制流程

    固定翼控制流程 主文件夹 子文件 fw att control位于src moudle文件夹下 fw att control main c 主文件 fw att control params c 主文件参数 CMakeList attitu
  • 固定翼位置控制_Tecs

    Tecs在位置控制中主要控制纵向的高度 xff0c 因为升降舵可以控制飞机的高度 xff0c 油门可以控制飞机的速度 xff0c 但是单单通过升降舵改变高度会使速度下降或者上升 xff0c 单单通过油门改变速度会使高度改变 xff0c 所以
  • 固定翼位置控制_L1

    L1算法控制航向 飞机从现在位置到设定位置 xff0c 需要进行转弯 转弯需要一个横向的加速度来改变速度的方向 这里横向加速度的计算公式 a 61 V2R 又因为R 61 2 sin L1 可得 a 61 2 V2L1 sin L1是现在位
  • 存储过程懂不懂

    存储过程的官方定义是这么说的 xff1a 存储过程 xff08 Stored Procedure xff09 是一组为了完成特定功能的 SQL 语句集 xff0c 经编译后存储在数据库中 用户通过指定存储过程的名字并给出参数 xff08 如
  • PX4多旋翼位置控制

    多悬翼的位置控制由内外环控制 xff0c 外环P控制作用于位置差 xff0c 产生期望速度 xff0c 内环PID作用于速度差 xff0c 产生期望油门 xff0c 然后将油门解算成期望姿态 外环位置控制的三种控制源 1 Manual 手动
  • PX4混控器定义

    PX4混控 把输入指令 分配给电机以及舵机的执行器 信号传递 Actuators id 61 ORB ID actuator controls 0 0号控制组 Orb publish actuators id actuators 0 pub
  • Linux--Ubuntu18.04交叉编译链;多窗口终端;彻底删除不用的虚拟机镜像

    文章目录 建立共享文件夹交叉编译查看是否安装了交叉编译工具安装交叉编译工具链退出root模式 多窗口终端 Terminator彻底删除不用的虚拟机镜像 建立共享文件夹 实现windows系统与虚拟机中的ubuntu之间的文件共享 PC机新建
  • 准确率,召回率,mAP(mean average precision)解释

    准确率Precision 召回率Recall 其实这个翻译相当蛋疼 recall最合理的翻译应该是 查全率 而Precision的最合理的翻译应该是查准率 这样就很容易理解了 xff0c 假设一个班级有10个学生 xff0c 5男5女 你用
  • Android 开发使用 Java 8 中Lambda 表达式功能

    简介 Android开发支持所有 Java 7 语言功能 xff0c 以及一部分 Java 8 语言功能 xff08 具体因平台版本而异 xff09 注意 xff1a 在开发应用时 xff0c 可以选择使用 Java 8 语言功能 您可以将
  • 浅谈 for循环

    浅谈for循环 xff0c for循环习题讲解 文章多看几遍吧 相信你一定会收获不少哇 什么是循环 xff1f 我认为循环就是把一个步骤一直重复执行的操作 如果没有终止条件 xff0c 那么这一步骤就会一直执行下去 xff0c 直到地老天昏
  • 给Jetson Nano更换eMMC闪存(扩容)

    7月4日更新 xff1a 添加了有关问题的解释与探讨 xff08 文末 xff0c 下一篇文章 xff09 7月5日更新 xff1a 添加了效果图 xff08 文末 xff09 7月8日更新 xff1a 添加了视频 b站 xff1a BV1
  • Linux下安装Anaconda3,这个教程一定要看!

    前言 大家好 xff0c 我是爱写Bug的麦洛 由于工作需要 xff0c 要为客户搭建Python开发环境 作为从来没有接触过Python的小白 xff0c 为了完成任务 xff0c 也是破费周折 xff0c 请教了身边做Python的朋友
  • Stm32F303进入bootloader重新烧录程序

    STM32F3飞控或开发板无法进入bootloader重新进行烧录固件程序的解决方案 F3系列的MCU无法进入bootloader 前提准备开始F4和F3的不同 F3系列的MCU无法进入bootloader 前几日找了一块F3的飞控板 刷入
  • 存储过程进阶(vb.net+SQL Server2008环境)

    写过一篇 存储过程入门 的博客 xff0c 那仅仅是入门 xff0c 下面和大家一起深入学习存储过程 xff08 也许以后还会有更深入 xff09 以经典的注册为例子 xff0c 篇幅有限只写了核心部分 xff0c 其他略过 无参数无返回值
  • 【Spring Boot 2.0学习之旅-06-4】Servlet3.0注解的自定义原生Listener监听器实战

    第六章 SpringBoot拦截器实战和Servlet3 0自定义Filter和Listener 06 4 SpringBoot2 x自定义拦截器实战以及新旧配置对比 1 过滤器与拦截器的区别 过滤器与拦截器触发时机不一样 xff0c 过滤
  • 【Spring Boot 2.0学习之旅-07】SpringBoot常用starter介绍和整合模板Freemaker、Thymeleaf

    第七章 SpringBoot常用starter介绍和整合模板Freemaker thymeleaf 07 1 SpringBoot Starter讲解 1 Spring starter是什么 starter是SpringBoot中的一个新发
  • 【Spring Boot 2.0学习之旅-08】SpringBoot数据库操作之整合Mybatis和事务讲解

    第八章 数据库操作之整合Mybatis和事务讲解 08 1 Spring2 x持久化数据方式介绍 简介 xff1a 介绍近几年常用的访问数据库的方式和优缺点 1 原始java访问数据库 开发流程麻烦 1 注册驱动 加载驱动 Class fo
  • 【Spring Boot 2.0学习之旅-09】SpringBoot2.x整合Redis实战

    第九章 SpringBoot2 x整合Redis实战 09 1 分布式缓存Redis介绍 简介 讲解为什么要用缓存和介绍什么是Redis xff0c 新手练习工具 1 redis官网 https redis io download 2 新手
  • 【Spring Boot 2.0学习之旅-10】SpringBoot整合定时任务和异步任务处理

    第十章 SpringBoot整合定时任务和异步任务处理 10 1 SpringBoot定时任务schedule讲解 1 定时器比较 什么是定时任务 xff0c 使用场景 xff1f 比如八月十五 xff0c 定时任务会轮询 xff0c 加载