当前位置: 首页 > news >正文

如何做网站页面免费的女教师遭网课入侵直播录屏曝光se

如何做网站页面免费的,女教师遭网课入侵直播录屏曝光se,女孩更严重的新冠异常,as3 xml 网站模板 下载Quartz简介 Job 表示一个工作,要执行的具体业务内容。 JobDetail 表示一个具体的可执行的调度程序,Job 是这个可执行程调度程序所要执行的内容,另外 JobDetail 还包含了这个任务调度的方案和策略。 Trigger 代表一个调度参数的配置&#xf…

Quartz简介

Job 表示一个工作,要执行的具体业务内容

JobDetail 表示一个具体的可执行的调度程序,Job 是这个可执行程调度程序所要执行的内容,另外 JobDetail 还包含了这个任务调度的方案和策略。

Trigger 代表一个调度参数的配置,什么时候去调。

Scheduler 代表一个调度容器,一个调度容器中可以注册多个 JobDetail 和 Trigger。当 Trigger 与 JobDetail 组合,就可以被 Scheduler 容器调度了。

案例

背景

系统中有一张自定义的定时任务表,需要实现动态的添加、修改、删除、启停定时任务等功能,定时任务里包含了业务需要执行的按设置周期执行的代码

由于不想使用Quartz的数据存储功能,所以下面实现里直接使用了这张自定义的表,以及使用了Quartz的任务调度触发功能

实现步骤

1. 引入依赖

<dependency><groupId>org.springframework.boot</groupId><artifactId>spring-boot-starter-quartz</artifactId><version>2.7.18</version>
</dependency>

2. 添加配置类

@Configuration
public class ScheduleQuartzConfig {@Beanpublic Scheduler scheduler() throws SchedulerException {Scheduler scheduler = schedulerFactoryBean().getScheduler();return scheduler;}@Beanpublic SchedulerFactoryBean schedulerFactoryBean() {Properties properties = new Properties();properties.setProperty("org.quartz.threadPool.threadCount", "10");properties.setProperty("org.quartz.threadPool.threadNamePrefix","quartz_worker");SchedulerFactoryBean factory = new SchedulerFactoryBean();factory.setSchedulerName("QUARTZ_SCHEDULER");factory.setQuartzProperties(properties);return factory;}
}

3. 编写Job类

该类就是将来要定时执行的业务代码,具体代码路径根据实际情况规划即可,重点是继承 QuartzJobBean,重写 executeInternal 方法

//锁定机制,以确保在同一时间只有一个任务实例运行
@DisallowConcurrentExecution
public class MyJob extends QuartzJobBeanprivate final static Logger logger = LoggerFactory.getLogger(PushPvImitateDataJob.class);@Overrideprotected void executeInternal(JobExecutionContext context) throws JobExecutionException {//业务代码logger.info("开始执行业务代码了。。。");try {Thread.sleep(6000);} catch (InterruptedException e) {e.printStackTrace();}	logger.info("业务代码执行完成了!!!!");}
}

4. 编写定时任务表的实体类

ScheduleLog.java

@Data
public class ScheduleLog {private Integer id;private String name; //任务名称private String jobClassName; //任务的实现类 如:xxx.xxx.xx.MyJobprivate String cronExpression; //触发时机表达式,比如每5秒执行一次 0/5 * * * * ?private Integer status; //状态:0 启动 1 禁用private String remark;private Long createTime;private Long updateTime;private Long lastTime; //上一次执行时间private Long nextTime; //下一次执行时间private String lastTimeText;private String nextTimeText;
}

5. 创建管理定时任务的工具类

@Component
public class ScheduleQuartzManage {private static final Logger logger = LoggerFactory.getLogger(ScheduleQuartzManage.class);/*** 创建定时任务 定时任务创建之后默认启动状态** @param scheduler:    调度器* @param scheduleLog: 报告订阅对象* @return: void**/public void createScheduleJob(Scheduler scheduler, ScheduleLog scheduleLog) throws SchedulerException {//获取到定时任务的执行类  必须是类的绝对路径名称//定时任务类需要是job类的具体实现 QuartzJobBean是job的抽象类。
//        Class<? extends Job> jobClass = PushPvImitateDataJob.class;Class<? extends Job> jobClass = null;try {jobClass = (Class<? extends Job>) Class.forName(scheduleLog.getJobClassName());} catch (ClassNotFoundException e) {e.printStackTrace();}// 构建定时任务信息JobDetail jobDetail = JobBuilder.newJob(jobClass).withIdentity(scheduleLog.getId().toString(),"jobGroup").usingJobData("id",scheduleLog.getId()).build();// 设置定时任务执行方式CronScheduleBuilder scheduleBuilder = CronScheduleBuilder.cronSchedule(scheduleLog.getCronExpression());// 构建触发器trigger// 如果已经有下一次时间,就设置为下一次时间为触发时间CronTrigger trigger;if (!Objects.isNull(scheduleLog.getNextTime())) {Date date = new Date(scheduleLog.getNextTime());trigger = TriggerBuilder.newTrigger().startAt(date).withIdentity(scheduleLog.getId().toString(), "jobGroup").withSchedule(scheduleBuilder).build();} else {trigger = TriggerBuilder.newTrigger().withIdentity(scheduleLog.getId().toString(),"jobGroup").withSchedule(scheduleBuilder).build();}scheduler.scheduleJob(jobDetail, trigger);// 设置下次执行时间//long nextTime = trigger.getNextFireTime().getTime();//LocalDateTime nextTime = DateUtil.dateToLocalDate(trigger.getNextFireTime());//logger.info("下次一执行时间:{}",DateUtil.formatDateTime(new Date(nextTime)));//scheduleLog.setNextTime(nextTime);}/*** 根据任务名称暂停定时任务** @param scheduler 调度器* @param jobName  定时任务名称(这里直接用ReportSubscribePO的Id)* @throws SchedulerException*/public void pauseScheduleJob(Scheduler scheduler, String jobName) throws SchedulerException {JobKey jobKey = JobKey.jobKey(jobName, "jobGroup");scheduler.pauseJob(jobKey);}/*** 根据任务名称恢复定时任务** @param scheduler 调度器* @param scheduleLog  定时任务名称(这里直接用ReportSubscribePO的Id)* @throws SchedulerException*/public void resumeScheduleJob(Scheduler scheduler, ScheduleLog scheduleLog) throws SchedulerException {// 判断当前任务是否在调度中Set<JobKey> jobKeys = scheduler.getJobKeys(GroupMatcher.groupEquals("jobGroup"));List<JobKey> thisNameJobs = jobKeys.stream().filter(jobKey -> Objects.equals(scheduleLog.getId().toString(), jobKey.getName())).collect(Collectors.toList());if (thisNameJobs.size() > 0){JobKey jobKey = JobKey.jobKey(scheduleLog.getId().toString(), "jobGroup");scheduler.resumeJob(jobKey);// 下一次执行时间设置回去Trigger trigger = scheduler.getTrigger(TriggerKey.triggerKey(scheduleLog.getId().toString(), "jobGroup"));long nextTime = trigger.getNextFireTime().getTime();scheduleLog.setNextTime(nextTime);}else {createScheduleJob(scheduler, scheduleLog);}}/*** 更新定时任务** @param scheduler    调度器* @param scheduleLog 报告订阅对象* @throws SchedulerException*/public void updateScheduleJob(Scheduler scheduler, ScheduleLog scheduleLog) throws SchedulerException {//获取到对应任务的触发器TriggerKey triggerKey = TriggerKey.triggerKey(scheduleLog.getId().toString(),"jobGroup");//设置定时任务执行方式CronScheduleBuilder scheduleBuilder = CronScheduleBuilder.cronSchedule(scheduleLog.getCronExpression());//重新构建任务的触发器triggerCronTrigger trigger = (CronTrigger) scheduler.getTrigger(triggerKey);if (trigger == null){return;}//  trigger = trigger.getTriggerBuilder().withIdentity(triggerKey).withSchedule(scheduleBuilder).build();trigger = TriggerBuilder.newTrigger().startNow().withIdentity(scheduleLog.getId().toString(), "jobGroup").withSchedule(scheduleBuilder).build();//重置对应的jobscheduler.rescheduleJob(triggerKey, trigger);scheduleLog.setNextTime(trigger.getNextFireTime().getTime());}/*** 根据定时任务名称从调度器当中删除定时任务** @param scheduler 调度器* @param jobName  定时任务名称 (这里直接用 ScheduleLog 的Id)* @throws SchedulerException*/public void deleteScheduleJob(Scheduler scheduler, String jobName) throws SchedulerException {JobKey jobKey = JobKey.jobKey(jobName,"jobGroup");scheduler.deleteJob(jobKey);}
}

6. 项目启动时做任务初始化

这里我直接让service实现了CommandLineRunner,然后在run()方法中,将初始化逻辑写入进来,让数据库中的持久化的任务全部添加进内存中。

@Service
public class ScheduleLogServiceImpl implements ScheduleLogService, CommandLineRunnerprivate final static Logger logger = LoggerFactory.getLogger(ScheduleLogServiceImpl.class);@Autowiredprivate ScheduleLogDao scheduleLogDao;@Autowiredprivate ScheduleQuartzManage scheduleQuartzManage;@Autowiredprivate Scheduler scheduler; //这里的scheduler来源于配置@Overridepublic void run(String... args) throws Exception {// 初始化所有的已经启用的订阅List<ScheduleLog> enableSubs = getEnableScheduleList();logger.info("需要初始化的任务个数:{}", enableSubs.size());for (ScheduleLog sub : enableSubs) {try {logger.info("开始初始化订阅任务,任务name:{}", sub.getName());scheduleQuartzManage.createScheduleJob(scheduler, sub);} catch (Exception e) {logger.error("启动时初始化订阅任务失败:{}", e.getMessage());}}}@Overridepublic List<ScheduleLog> getEnableScheduleList() {HashMap<String, Object> param = new HashMap<>();param.put("status",1);List<ScheduleLog> list = scheduleLogDao.getList(param);return list;}@Overridepublic boolean add(Map data) {data.put("createTime", DateUtil.currentSeconds());Integer add = scheduleLogDao.add(data);if(add > 0){//创建调度器data.put("id",add);ScheduleLog scheduleLog = BeanUtil.mapToBean(data, ScheduleLog.class,false,null);if(scheduleLog.getStatus() < 1){return true;}try {scheduleQuartzManage.createScheduleJob(scheduler, scheduleLog);} catch (SchedulerException e) {e.printStackTrace();}return true;}return false;}@Overridepublic boolean del(Integer id) {Integer del = scheduleLogDao.del(id);if(del > 0){try {scheduleQuartzManage.deleteScheduleJob(scheduler,String.valueOf(id));} catch (SchedulerException e) {e.printStackTrace();}return true;}return false;}@Overridepublic boolean edit(Map data) {data.put("updateTime",DateUtil.currentSeconds());Integer save = scheduleLogDao.save(data);if(save > 0){try {ScheduleLog scheduleLog = getDetail((Integer) data.get("id"));if(data.get("status").equals(0)){//关闭scheduleQuartzManage.deleteScheduleJob(scheduler,data.get("id").toString());}else{//开启scheduleQuartzManage.deleteScheduleJob(scheduler,data.get("id").toString());scheduleQuartzManage.createScheduleJob(scheduler,scheduleLog);}} catch (SchedulerException e) {e.printStackTrace();}return true;}return false;}
}

至此基本就实现了定时任务的管理了,controller 里的内容包含了对定时任务进行管理的接口,就不写了

总结

  1. 同一个任务是否可以并行执行,可参考第3步设置
  2. 每次项目重新部署后,自动加载数据库中的定时任务
  3. Quartz在发生异常时会重试一次,注意异常处理,可在第3步中处理

参考链接:https://juejin.cn/post/7054762566035193869#heading-7

Cron表达式

不管是Spring自带的定时任务实现,还是SpringBoot整合Quartz的定时任务实现,其触发器都支持用corn表达式来表示。

corn表达式是一个字符串,有6或7个域,域之间是用空格进行间隔。

从左到右每个域表示的含义如下:

第几个域英文释义允许值备注
Seconds0~59
Minutes0~59
Hours0~23
DayOfMonth1-31
Month1-12或月份简写
DayOfWeek1-7或星期简写星期,1表示SUN,在day-of-week字段用”6#3”指这个月第3个周五(6指周五,3指第3个)。如果指定的日期不存在,触发器就不会触发
Year1970~2099

然后,某些域还支持部分特殊字符,特殊字符的含义如下:

特殊字符含义及注意事项
*任意值
?占位符,只能在第四域和第六域中使用,表示未说明的值,即不关心它为何值
-区间,表示区间内有效
/固定间隔,符号前表示开始时间,符号后表示每次递增的值;
,枚举有效值的间隔符,表示附加一个可能值
L表示该区间的最后一个有效值,只能在第四域和第六域中使用, L(“last”) (“last”) “L” 用在day-of-month字段意思是 “这个月最后一天”;用在 day-of-week字段, 它简单意思是 “7” or “SAT”。 如果在day-of-week字段里和数字联合使用,它的意思就是 “这个月的最后一个星期几” – 例如: “6L” means “这个月的最后一个星期五”. 当我们用“L”时,不指明一个列表值或者范围是很重要的,不然的话,我们会得到一些意想不到的结果。
W表示离指定日期的最近的有效工作日,(周一-周五为工作日),W(“weekday”) 只能用在day-of-month字段。用来描叙最接近指定天的工作日(周一到周五)。例如:在day-of-month字段用“15W”指“最接近这个月第15天的工作日”,即如果这个月第15天是周六,那么触发器将会在这个月第14天即周五触发;如果这个月第15天是周日,那么触发器将会在这个月第16天即周一触发;如果这个月第15天是周二,那么就在触发器这天触发,注意一点:这个用法只会在当前月计算值,不会越过当前月。“W”字符仅能在day-of-month指明一天,不能是一个范围或列表。也可以用“LW”来指定这个月的最后一个工作日。

常用corn表达式例子含义说明:

corn表示式表达式含义
*/10 * * * * ? *每隔10秒执行一次
0 30 1 * * ? *每天凌晨1点30分0秒开始执行
0 0 10,14,16 * * ?每天10点、14点、16点执行一次
0 15 10 L * ?每个月最后一天的10点15分执行一次
0 15 10 ? * 6L每月的最后一个星期五上午10:15触发
0 15 10 15 * ?每月15日上午10:15触发
0 15 10 ? * 6#3每月的第三个星期五上午10:15触发
0 15 10 ? * 6L 2018-20202018年到2020年每个月最后一个星期五的10:15执行

校验地址:https://www.bejson.com/othertools/cronvalidate/

http://www.jinmujx.cn/news/118096.html

相关文章:

  • 珠海响应式网站制作北京seo关键词
  • 营销网站建设网站制作公司营销咨询服务
  • 可以分4天做任务的网站女教师网课入侵录屏冫
  • 杭州人防质监站网址曹操博客seo
  • 建设一个网站电话营销
  • 动漫网站在线免费观看网图识别在线百度
  • 做网站有陪标现象吗seo站长综合查询
  • 永久免费crm管理系统电池优化大师下载
  • 网站 做内容分发资格百度一下就会知道了
  • 我想建一个网站怎么建武汉百度seo网站优化
  • 域名可以做网站吗百度指数网站
  • 网站建设ppt榆林百度seo
  • 17做网店网站池尾百度搜索热度指数
  • 网站开发价格评估海外短视频软件
  • 黑马培训收费seo快速排名软件网站
  • 做网站有什么书百度新闻最新消息
  • wordpress播放直播seo搜索引擎优化排名哪家更专业
  • 微商城网站建设怎么样指数分布
  • 大连的网站设计公司湛江百度网站快速排名
  • 济南互联网选号网站湖南seo优化
  • 网站制作公司服务怎样创建一个网站
  • iis 新建网站蔡甸seo排名公司
  • 制作灯笼的手工做法幼儿园宁波优化seo软件公司
  • wordpress图片工具位置sem优化是什么
  • 网站制作的趋势百度seo优化分析
  • 济南网站建设推荐企优互联不错网站定制
  • 创建一个网站需要做哪些工作优秀软文范例100字
  • 网页设计站点小程序制作一个需要多少钱
  • 货运配载做网站免费外国网站浏览器
  • 建设企业网站的重要性石家庄百度关键词优化