二十、Spring Task
定时任务框架:Spring Task是Spring框架提供的任务调度工具,可以按照约定的时间自动执行某个代码逻辑。
1、Spring Task cron 表达式
cron表达式在线生成器: https://cron.qqe2.com/
cron表达式其实就是一个字符串,通过cron表达式可以定义任务触发的时间。
构成规则:分为6或7个域,由空格分隔开,每个域代表一个含义
每个域的含义分别为:秒、分钟、小时、日、月、周、年(可选)
2、实现步骤及案例
1、导入maven坐标 spring context (已存在) ,下面两个包都包含对应的包不需要导包(SpringBoot项目)
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter</artifactId>
</dependency>
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-web</artifactId>
</dependency>
2、在启动类添加注解
@EnableScheduling
开启任务调度
@SpringBootApplication
@EnableScheduling
public class HumanResourcesApplication {
public static void main(String[] args) {
SpringApplication.run(HumanResourcesApplication.class, args);
}
}
3、自定义定时任务类
@Component
public class TaskTest {
/**
* 每5秒执行一次
*/
@Scheduled(cron = "0/5 * * * * ? ")
public void test(){
System.out.println("定时任务执行了:"+ LocalDateTime.now());
}
}
4、实际项目中的使用:订单定时任务
@Component
@Slf4j
public class OrderTask {
@Autowired
private OrdersMapper ordersMapper;
/**
* 订单超时未支付取消,每1分钟执行一次操作
*/
@Transactional // 开启事务
@Scheduled(cron="0 0/30 * * * ?")
public void overdueOrder(){
//1、先查询出还没有支付切超时的订单
// 当前时间减去15分钟,十五分钟前的时间
LocalDateTime nowReduce15Minutes=LocalDateTime.now().minusMinutes(15);
Orders orders=new Orders();
orders.setStatus(Orders.PENDING_PAYMENT); //订单状态:待支付
orders.setOrderTime(nowReduce15Minutes);
List<Orders> ordersList=ordersMapper.selectOverdueOrder(orders);
log.info("待付款的点单:"+ordersList.toString());
//2、修改订单状态为已取消
if (ordersList!=null || ordersList.size()>0){
for (Orders order : ordersList) {
order.setStatus(Orders.CANCELLED);
order.setCancelReason("订单超时,自动取消");
order.setCancelTime(LocalDateTime.now());
ordersMapper.update(order);
}
}
}
/**
* 订单派送,如果订单在店铺打样或者在凌晨1点还在配送中的话,将订单状态改为已完成
*/
@Transactional
@Scheduled(cron="* * 1 * * ?")
public void deliveryOrder(){
//1、查询出正在配送中的订单
Orders orders=new Orders();
orders.setStatus(Orders.DELIVERY_IN_PROGRESS);
orders.setOrderTime(LocalDateTime.now().minusHours(1)); // 1小时前的时间
List<Orders> ordersList=ordersMapper.selectOverdueOrder(orders);
log.info("正在配送中的订单:"+ordersList.toString());
//2、修改订单状态为已完成
if (ordersList!=null || ordersList.size()>0){
for (Orders order : ordersList) {
order.setStatus(Orders.COMPLETED);
order.setDeliveryTime(LocalDateTime.now());
ordersMapper.update(order);
}
}
}
}