作者:df0134330 | 来源:互联网 | 2023-09-15 10:19
首次写博,如有不对(妥)之处,欢迎指正!quartz定时插件,对于新入职员工,没有真实开发经验的新人很有可能并没有接触过,网上的博客呢又看不太懂,因此记录一些自己学习并对quart
首次写博,如有不对(妥)之处,欢迎指正!
quartz定时插件,对于新入职员工,没有真实开发经验的新人很有可能并没有接触过,网上的博客呢又看不太懂,因此记录一些自己学习并对quartz进行基础使用的过程。
当然我就是呢。
然而在实际项目开发中Web应用是不可缺少的。 定时任务的场景可以说非常广泛,比如某些视频网站,购买会员后,每天会给会员送成长值,每月会给会员送一些电影券;
比如在保证最终一致性的场景中,往往利用定时任务调度进行一些比对工作;比如一些定时需要生成的报表、邮件;比如一些需要定时清理数据的任务等。所以我们提供方便友好的web界面,实现动态管理任务,可以达到动态控制定时任务启动、暂停、重启、删除、添加、修改等操作,极大地方便了开发过程。
一:对于传统springMVC项目(maven管理):
1.导入相关依赖:
1
2
3 <dependency>
4 <groupId>org.quartz-schedulergroupId>
5 <artifactId>quartzartifactId>
6 <version>2.3.1version>
7 dependency>
8
9
10 <dependency>
11 <groupId>org.quartz-schedulergroupId>
12 <artifactId>quartz-jobsartifactId>
13 <version>2.3.1version>
14 dependency>
2.写一个自己的job类
1 public class MyJob {
2 public void run() {
3 SimpleDateFormat format = new SimpleDateFormat("yyyy- MM-dd hh:mm:ss");
4 System.out.print(format.format(new Date().getTime()));
5 }
6 }
3.配置文件: 如果是多个任务,这些配置除了任务调度者都需要写多个
1
2 <bean id="myjob" class="com.yzy.MyJob">bean>
3
4 <bean id="jobDetail" class="org.springframework.scheduling.quartz.MethodInvokingJobDetailFactoryBean">
5
6 <property name="targetObject" ref="myjob">property>
7
8 <property name="targetMethod" value="run">property>
9 bean>
10
11 <bean id="trigger1" class="org.springframework.scheduling.quartz.CronTriggerFactoryBean">
12
13 <property name="jobDetail" ref="jobDetail">property>
14
15 <property name="cronExpression" value="1/2 * * * * ?">property>
16 bean>
17
18 <bean class="org.springframework.scheduling.quartz.SchedulerFactoryBean">
19
20 <property name="triggers">
21
22 <list>
23 <ref bean="trigger1"/>
24 list>
25 property>
26
27 <property name="cronExpression" value="1/2 * * * * ?">property>
28 bean>
4.使用
1 //①:
2 public static void main(String[] args) {
3 new ClassPathXmlApplicationContext("classpath:application.xml");//加载写好的配置文件
4 }
5
6 //或者使用②:在web.xml中:
7
8 contextConfigLocation
9 classpath:application.xml
10
11
12 class>org.springframework.web.context.ContextLoaderListenerclass>
13
14 //两种方式
5.然后:然后就自动执行了呗:启动一秒后每隔两秒执行一次 => 1/2 * * * * ?
二:对于springboot项目:
1.导入依赖
1 <dependency>
2 <groupId>org.springframework.bootgroupId>
3 <artifactId>spring-boot-starter-quartzartifactId>
4 dependency>
5 <dependency>
6 <groupId>org.quartz-schedulergroupId>
7 <artifactId>quartz-jobsartifactId>
8 <version>2.3.1version>
9 dependency>
2.写个自己的job类(MyJob.class),此类必须实现quartz自带的Job接口,此接口只有一个方法需要实现,里边是的方法实现内容是自定义的
1 @Configuration //此注解一定要加不然报错: Job instantiation failed
2 public class MyJob implements Job {
3 @Override
4 public void execute(JobExecutionContext context) throws JobExecutionException {
5 SimpleDateFormat format = new SimpleDateFormat("yyyy-MM-dd hh:mm:ss");
6 System.out.print(format.format(new Date().getTime()));
7 }
8 }
3. 编程式配置
1 @Configuration //声明配置文件,声明之后spring才会把它当作配置文件去加载,否则不会加载
2 public class QuzrtzConfig {
3 //配置任务详情
4 @Bean
5 public JobDetail jobDetail(){
6 return JobBuilder.newJob(MyJob.class).withIdentity("beifenKJob","group1")//配置详情名称,以及所在详情组名(与下边的触发器组名没有关系),(方便点调度者Scheduler对其进行相关操作)
7 .storeDurably().build();
8 }
9 //配置触发器,并将所要加载的任务详情给他;
10 @Bean
11 public Trigger triggerDetail(JobDetail jobDetail){
12 return TriggerBuilder.newTrigger().forJob(jobDetail)
13 .withIdentity("beifenKT","group1")//配置触发器名称,以及所在触发器组名,(方便点调度者对其进行相关操作)上边xml的方式也可以,但是我没写配值不过是继续添加节点而已;
14 .withSchedule(cronSchedule("2/2 * * * * ?"))
15 .build();
16 }
17 }
4.boot项目入口直接启动。
三:
1.下边springboot拓展一点,刚开始我不知道如何去控制job,启动的时候不让job去执行,而是让前台,也就是使用者去控制是否开启或者停止该作业;
因为一但启动项目就自动执行了,想要让他在启动项目的时候为关闭状态,使用者去在前端操作是否执行。
2.这点在网上找了好久都没有找到解决办法(反正我是没找到,放低要求去找停止任务的方法,百度都没有);网上的都是让调度器shutdown()掉,多作业job的增删改查之类的,
但是与我所描述的目的完全不同。
3.后来琦哥也就是我的社会上第一个直接领导者,给了我一个别人做好的完整的项目,我在这项目中找到了让停止作业和开始作业的方法(其实是自己没好好看调度器Scheduler的源码,都是英语,看起来异常不舒服也就没仔细看)。但我想不通的是网上为啥没有,还是我有点蠢没找到?那首先这一点我给排除了,因为不蠢嘛。
4.下面分享停止作业与打开的作业的方法:scheduler.resumeJob(key);调度器开始作业的方法 ; scheduler.pauseJob(key);调度器停止作业的方法
这里有必要说明一下,scheduler.start(),scheduler.shutdown(),scheduler.unscheduleJob(triggerKey),scheduler.standby()这些方法是
唤醒调度器,药晕调度器,删除作业(你都删除了,下次调用呢?再敲代码吗?还是再重新注入,应该是注入),停止所有作业,等等还有一些添加,修改。大哥我要的是暂停,暂停懂否?
这就是网上告诉我的答案,和我描述的两回事嘛,他们都在干什么,的确有部分人标题党?写的开启和暂停你给我看这些。
5.我的代码:首先这个代码拓展性不高,只能开始和停止特定的作业(也就是特定的配置类实例),高的话需要传参作业key,因为作业比较少就没这样做(偷个懒)。
而且还没有做验证,后期会加上,验证嘛没什么新鲜的。先这样,主要是功能嘛。
1 @Controller
2 @RequestMapping("/admin/db")
3 public class DBController {
4 @Autowired
5 public Scheduler scheduler;//装载调度者
@Autowired
6 QuartzConfig scheduleJob;//配置类实例,就是上边 “3. 编程式配置 ”
7
8 /**
9 * 开始数据库备份,
10 * */
11 @RequestMapping("/startDb")
12 @ResponseBody
13 public boolean startDb(String cron) {//需要传入cron表达式,这里没有写死。
14 //crudJob.deleteJob();
15 boolean s = false;
16 try{
17 JobKey key = scheduleJob.jobDetail().getKey();
18 scheduler.resumeJob(key);
19 s = true;
20 }catch (Exception e){
21 e.printStackTrace();
22 }
23 return s;
24 }
25
26 /**
27 * 停止数据库备份,
28 * */
29 @RequestMapping("/stopDb")
30 @ResponseBody
31 public boolean stopDb(){
32 boolean s = false;
33 try {
34 JobKey key = scheduleJob.jobDetail().getKey();
35 scheduler.pauseJob(key);//核心方法:调度器类中自带的方法
36 s = true;
37 }catch (Exception e){
38 e.printStackTrace();
39 }
40 return s;
41 }
42 }
6.然后呢,是可以停止与开始了,但是启动后依然会自动执行,于是我想到了让程序启动的时候去执行一次停止的方法。以下是我的代码
1 @Component//一定要有,否则不会执行
2 @Order(value = 1)//配置执行顺序,如果有多个需要在项目启动时执行的类的话,可以理解为权重,这里是value越小,越先执行
3 public class StopBei implements ApplicationRunner {//这个类也必须继承ApplicationRunner,如果不清楚:那就是springboot你没有学。
4
5 @Autowired
6 public Scheduler scheduler;
7
8 BaseDataU bs = new BaseDataU();
9 QuzrtzConfig scheduleJob = new QuzrtzConfig();
10
11 @Override
12 public void run(ApplicationArguments args) throws Exception {
13 JobKey key = scheduleJob.jobDetail().getKey();
14 scheduler.pauseJob(key);//guanbi
15 System.out.print("===========================已经停止"+args.getClass()+"============================================");
16 }
17 }
很显然大功告成,总感觉这个方式不是很好,感觉quartz应该有一个作业的管理,就是项目启动时是否执行作业的方法一个trueOrfalse,什么的,无奈没有找到,
如果哪位帅哥或者美眉有这样直接的方法可以留言给我,谢谢。萌新们,我们一起加油!!!。