发表于: 2019-10-28 12:54:43
1 945
今天完成的事情:(一定要写非常细致的内容,比如说学会了盒子模型,了解了Margin)
前端开始给新增banner加上上床图片,这个新增一个请求参数。
继续学习springboot中的定时任务:
1)JobDetail:望文生义就是描述任务的相关情况;
2)Trigger:描述出发Job执行的时间触发规则。有SimpleTrigger和CronTrigger两个子类代表两种方式,一种是每隔多少分钟小时执行,则用SimpleTrigger;另一种是日历相关的重复时间间隔,如每天凌晨,每周星期一运行的话,通过Cron表达式便可定义出复杂的调度方案。
3)Scheduler:代表一个Quartz的独立运行容器,Trigger和JobDetail要注册到Scheduler中才会生效,也就是让调度器知道有哪些触发器和任务,才能进行按规则进行调度任务。
动态:基于接口
基于接口(SchedulingConfigurer)
创建定时器
数据库准备好数据之后,我们编写定时任务,注意这里添加的是TriggerTask,目的是循环读取我们在数据库设置好的执行周期,以及执行相关定时任务的内容。
具体代码如下:
package com.jnshu.quartz.schedule;
import org.apache.ibatis.annotations.Mapper;
import org.apache.ibatis.annotations.Select;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.context.annotation.Configuration;
import org.springframework.scheduling.annotation.EnableScheduling;
import org.springframework.scheduling.annotation.SchedulingConfigurer;
import org.springframework.scheduling.config.ScheduledTaskRegistrar;
import org.springframework.scheduling.support.CronTrigger;
import org.springframework.stereotype.Component;
import org.springframework.util.StringUtils;
import java.time.LocalDateTime;
@Component
@Configuration //1.主要用于标记配置类,兼备Component的效果。
@EnableScheduling // 2.开启定时任务
public class DynamicScheduleTask implements SchedulingConfigurer {
@Mapper
public interface CronMapper{
@Select("select cron from cron limit 1")
public String getCron();
}
@Autowired //注入mapper
@SuppressWarnings("all")
CronMapper cronMapper;
/**
* 执行定时任务
* */
@Override
public void configureTasks(ScheduledTaskRegistrar taskRegistrar) {
taskRegistrar.addTriggerTask(
//1.添加任务内容(Runnable)
() -> System.out.println("执行动态定时任务:"+ LocalDateTime.now().toLocalTime()),
//2.设置执行周期(Trigger)
triggerContext -> {
//2.1 从数据库获取执行周期
String cron=cronMapper.getCron();
//2.2 合法性校验
if (StringUtils.isEmpty(cron)){
//Omitted Code
}
//2.3 返回了执行周期(date)
return new CronTrigger(cron).nextExecutionTime(triggerContext);
}
);
}
}
有些最新的写法不是太懂 - > () ->
三、多线程定时任务
基于注解设定多线程定时任务
1、创建多线程定时任务
package com.jnshu.quartz.schedule;
import org.springframework.scheduling.annotation.Async;
import org.springframework.scheduling.annotation.EnableAsync;
import org.springframework.scheduling.annotation.EnableScheduling;
import org.springframework.scheduling.annotation.Scheduled;
import org.springframework.stereotype.Component;
import java.time.LocalDateTime;
//@Component注解用于对那些比较中立的类进行注释;
//相对与在持久层、业务层和控制层分别采用 @Repository、@Service 和 @Controller 对分层中的类进行注释
@Component
@EnableScheduling // 1.开启定时任务
@EnableAsync // 2.开启多线程
public class MultithreadScheduleTask {
@Async
@Scheduled(fixedDelay = 1000)//间隔一秒
public void first() throws InterruptedException{
System.out.println("第一个定时任务开始:"+ LocalDateTime.now().toLocalTime()+"\r\n线程:"+
Thread.currentThread().getName());
System.out.println();
Thread.sleep(1000*10);
}
@Async
@Scheduled(fixedDelay = 2000) //间隔2秒
public void second(){
System.out.println("第二个定时任务开始:"+LocalDateTime.now().toLocalTime()+"\r\n线程:"+
Thread.currentThread().getName());
System.out.println();
}
}
Cron Expressions
Cron-Expressions用于配置CronTrigger的实例。Cron Expressions是由七个子表达式组成的字符串,用于描述日程表的各个细节。这些子表达式用空格分隔,并表示:
- Seconds(秒)
- Minutes(分)
- Hours(时)
- Day-of-Month(几号)
- Month(几月)
- Day-of-Week(周几)
- Year (optional field)(几几年)
一个完整的Cron-Expressions的例子是字符串“0 0 12?* WED“ - 这意味着”每个星期三中午12:00“。
单个子表达式可以包含范围和/或列表。例如,可以用“MON-FRI”,“MON,WED,FRI”或甚至“MON-WED,SAT”代替前一个(例如“WED”)示例中的星期几字段。
通配符(' '字符)可用于说明该字段的“每个”可能的值。因此,前一个例子的“月”字段中的“”字符仅仅是“每个月”。因此,“星期几”字段中的“*”显然意味着“每周的每一天”。
所有字段都有一组可以指定的有效值。这些值应该是相当明显的 - 例如秒和分钟的数字0到59,数小时的值0到23。日期可以是1-31的任何值,但是您需要注意在给定的月份中有多少天!月份可以指定为1到12之间的值,或者使用字符串JAN,FEB,MAR,APR,MAY,JUN,JUL,AUG,SEP,OCT,NOV和DEC。星期几可以指定为1到7(1 =星期日)之间的值,或者使用字符串SUN,MON,TUE,WED,THU,FRI和SAT。
'/'字符可用于指定值的增量。例如,如果在“分钟”字段中输入“0/15”,则表示“每隔15分钟,从零开始”。如果您在“分钟”字段中使用“3/20”,则意味着“每隔20分钟,从三分钟开始” - 换句话说,它与“分钟”中的“3,23,43”相同领域。请注意“ / 35”的细微之处并不代表“每35分钟” - 这意味着“每隔35分钟,从零开始” - 或者换句话说,与指定“0,35”相同。
'?' 字符是允许的日期和星期几字段。用于指定“无特定值”。当您需要在两个字段中的一个字段中指定某个字符而不是另一个字段时,这很有用。请参阅下面的示例(和CronTrigger JavaDoc)以进行说明。
“L”字符允许用于月日和星期几字段。这个角色对于“最后”来说是短暂的,但是在这两个领域的每一个领域都有不同的含义。例如,“月”字段中的“L”表示“月的最后一天” - 1月31日,非闰年2月28日。如果在本周的某一天使用,它只是意味着“7”或“SAT”。但是如果在星期几的领域中再次使用这个值,就意味着“最后一个月的xxx日”,例如“6L”或“FRIL”都意味着“月的最后一个星期五”。您还可以指定从该月最后一天的偏移量,例如“L-3”,这意味着日历月份的第三个到最后一天。当使用'L'选项时,重要的是不要指定列表或值的范围,因为您会得到混乱/意外的结果。
“W”用于指定最近给定日期的工作日(星期一至星期五)。例如,如果要将“15W”指定为月日期字段的值,则意思是:“最近的平日到当月15日”。
'#'用于指定本月的“第n个”XXX工作日。例如,“星期几”字段中的“6#3”或“FRI#3”的值表示“本月的第三个星期五”。
以下是一些表达式及其含义的更多示例 - 您可以在JavaDoc中找到更多的org.quartz.CronExpression
“0 0/5 * * *?” //每5分钟就会触发一次
“10 0/5 * * *?” //每5分钟触发一次,分钟后10秒(即上午10时10分,上午10:05:10等)
“0 30 10-13?* WED,FRI“ //在每个星期三和星期五的10:30,11:30,12:30和13:30创建触发器的表达式
“0 0/30 8-9 5,20 *?” //每个月5日和20日上午8点至10点之间每半小时触发一次。请注意,触发器将不会在上午10点开始,仅在8:00,8:30,9:00和9:30
请注意,一些调度要求太复杂,无法用单一触发表示 - 例如“每上午9:00至10:00之间每5分钟,下午1:00至晚上10点之间每20分钟”一次。在这种情况下的解决方案是简单地创建两个触发器,并注册它们来运行相同的作业。
明天计划的事情:(一定要写非常细致的内容)
遇到的问题:(遇到什么困难,怎么解决的)
前端出现后台banner新增和编辑出现问题,参数没有传进来。
在我的新增之前做了一个判断请求参数是否为空的判断。
解决之后,出现一个新增banner不显示时间,,但是我这边数据已经传过去,前端也已经接收到了。
这个也解决了,然后就是点击上架的时候,前端这边会出现超过3个也可以进行上架,但是数据库是没有进行上架的操作,我后端代码已经进行了判断,没有进行上架,也返回了错误信息,但是前端这边需要做一个判断。
收获:(通过今天的学习,学到了什么知识)
评论