SpringBoot整合定时任务 Schedule定时任务器和Quartz定时任务框架

mac2024-04-17  28

定时器:

在一定时间内执行的所触发的方法。使用场景也挺多的,如一个系统的日志需要定期删除。

Schedule:

定时任务器:是spirng3.0以后自带的一个定时任务器。

使用:

第一步:在pom文件中添加schedule的坐标

<!--spring-boot的核心启动器--> <dependency> <groupId>org.springframework.boot</groupId> <artifactId>spring-boot-starter-web</artifactId> </dependency> <!--添加Schedule定时器--> <dependency> <groupId>org.springframework</groupId> <artifactId>spring-context-support</artifactId> </dependency> <!--开启test--> <dependency> <groupId>org.springframework.boot</groupId> <artifactId>spring-boot-starter-test</artifactId> <scope>test</scope> </dependency>

第二步:添加ScheduleDemo测试类

@Component public class ScheduleDemo { /** * 定时任务 * @Scheduled 设置定时任务 * cron 需要cron的表达式 是一个定时触发的字符串的表达式 * * cron表达式 * 分6字表达式和7字表达式 * * second minute hour day month week 6字表达式 * second minute hour day month week year 7字表达式 * * second 区间 [0,59] * minute 区间 [0,59] * hour 区间 [0,23] * day 区间 [1,31] * month 区间 [1,12] * week 区间 [1,7],注意 这里星期一代表7,星期填为6,外国的第一天是从7开始 * year 区间[1950,2099] * * 符号的作用: * 1.星号(*):可用在所有字段中,代表对应时间的每一刻,eg:*在分钟字段中代表,每一分钟执行 * 2.问号(?):占位符作用,通常指定无意义的值 * 3.减号(-):代表一个区间,表示在一个时间范围之内 10-12 * 4.逗号(,) 代表在一个范围内,1,4,5,6 在此序列内 * 5.斜杠(/):x/y代表一个等长序列,x为起始值,y为递增步数,0/15,若在秒中出现则是每隔15秒执行一次 * 等。 * * eg:@Scheduled(cron = "0 0 1 1 1,4,7,10 ?")//每个季度的一月一号1点执行 * */ @Scheduled(cron = "0/2 * * * * ?") public void scheduleMethod(){ System.out.println("触发 "+ new Date()); } }

第三步:在启动类中开启定时任务

@SpringBootApplication @EnableScheduling//开启schedule定时任务 public class App extends SpringBootServletInitializer { protected SpringApplicationBuilder configure(SpringApplicationBuilder builder) { return builder.sources(App.class); } public static void main(String[] args) { SpringApplication.run(App.class, args); } }

Quartz:

Quartz是OpenSymphony开源组织在Job scheduling领域又一个开源项目,它可以与J2EE与J2SE应用程序相结合也可以单独使用。Quartz可以用来创建简单或为运行十个,百个,甚至是好几万个Jobs这样复杂的程序。Jobs可以做成标准的Java组件或 EJBs。Quartz的最新版本为Quartz 2.3.0。

使用:

1.Job-任务 你要做什么事情

2.Trigger-触发器 什么时候去做

3.Schedule 任务调度 你什么时候去做什么事情.

第一步:在pom文件中添加Quartz的坐标

<?xml version="1.0" encoding="UTF-8"?> <project xmlns="http://maven.apache.org/POM/4.0.0" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd"> <modelVersion>4.0.0</modelVersion> <groupId>com.whut.schedule</groupId> <artifactId>spring-boot-schedule</artifactId> <version>1.0-SNAPSHOT</version> <parent> <groupId>org.springframework.boot</groupId> <artifactId>spring-boot-starter-parent</artifactId> <version>2.0.5.RELEASE</version> <relativePath/> <!-- lookup parent from repository --> </parent> <properties> <project.build.sourceEncoding>UTF-8</project.build.sourceEncoding> <project.reporting.outputEncoding>UTF-8</project.reporting.outputEncoding> <java.version>1.8</java.version> </properties> <dependencies> <!--spring-boot的核心启动器--> <dependency> <groupId>org.springframework.boot</groupId> <artifactId>spring-boot-starter-web</artifactId> </dependency> <!--添加Schedule定时器--> <dependency> <groupId>org.springframework</groupId> <artifactId>spring-context-support</artifactId> </dependency> <!--开启test--> <dependency> <groupId>org.springframework.boot</groupId> <artifactId>spring-boot-starter-test</artifactId> <scope>test</scope> </dependency> <!--Quartz的坐标--> <dependency> <groupId>org.quartz-scheduler</groupId> <artifactId>quartz</artifactId> <version>2.2.1</version> <exclusions> <exclusion> <artifactId>slf4j-api</artifactId> <groupId>org.slf4j</groupId> </exclusion> </exclusions> </dependency> <!--Spring tx 坐标--> <dependency> <groupId>org.springframework</groupId> <artifactId>spring-tx</artifactId> </dependency> </dependencies> </project>

第二步:编写QuartzDemo任务类

/** * 定义任务类 * 整合SpringBoot */ @Component public class QuartzDemo implements Job { @Override public void execute(JobExecutionContext jobExecutionContext) throws JobExecutionException { System.out.println("execute " + new Date()); } }

第三步:配置Quartz,编写QuartzConfig类来配置Quartz

@Configuration public class QuartzConfig { /** * 创建Job对象 *要去做什么 */ @Bean public JobDetailFactoryBean jobDetailFactoryBean(){ JobDetailFactoryBean factory = new JobDetailFactoryBean(); factory.setJobClass(QuartzDemo.class); return factory; } /** * 创建Trigger对象 * 什么时候去做 * 创建的简单的Trigger */ @Bean public SimpleTriggerFactoryBean simpleTriggerFactoryBean(JobDetailFactoryBean jobDetailFactoryBean){ SimpleTriggerFactoryBean factory = new SimpleTriggerFactoryBean(); //整合Job 关联Job // factory.setJobDetail(jobDetailFactoryBean.getObject()); //repeatInterval 执行的毫秒数 factory.setRepeatInterval(2000); //设置重复次数 factory.setRepeatCount(5); return factory; } /** * CronTrigger */ @Bean public CronTriggerFactoryBean cronTriggerFactoryBean(JobDetailFactoryBean jobDetailFactoryBean){ CronTriggerFactoryBean factory = new CronTriggerFactoryBean(); //关联Job factory.setJobDetail(jobDetailFactoryBean.getObject()); //设置CronTrigger factory.setCronExpression("0/2 * * * * ?"); return factory; } /** * 创建Scheduler对象 * 在什么时间去做什么事情 */ @Bean public SchedulerFactoryBean schedulerFactoryBean( SimpleTriggerFactoryBean simpleTriggerFactoryBean, MyAdaptableJobFactory myAdaptableJobFactory ){ SchedulerFactoryBean factory = new SchedulerFactoryBean(); //关联Trigger 可以关联CronTrigger factory.setTriggers(simpleTriggerFactoryBean.getObject()); return factory; } }

经过上述操作即可完成定时任务的整合。

Quartz:Quartz整合业务逻辑对象的注入

上述都是在测试是否能正常在特定时间内执行定时触发任务,没有关联业务逻辑代码。

给定场景:在特定时间内添加用户,这里简单化处理

一:新建测试服务类UserService

@Service public class UserService { public void addUser(){ System.out.println("add user :" + new Date()); } }

二:在任务类QuartzDemo中注入该任务类

/** * 定义任务类 * 整合SpringBoot */ @Component public class QuartzDemo implements Job { @Autowired private UserService userService; @Override public void execute(JobExecutionContext jobExecutionContext) throws JobExecutionException { System.out.println("execute " + new Date()); userService.addUser(); } }

当运行该项目时候会抛出这样的错误:

提示我们的UserService 没有注入进去。

原因:

QuartzDemo 对象的实例化完全交给了JobDetailFactoryBean来完成 * 实际上实例化采用反射机制来实现 * QuartzDemo 的实例化没有经过Spring的处理 * Spring注入需要注入对象和被注入对象全部都存在与Spring IOC容器中

这里需要我们手动将对象注入到SpingIOC容器中.

三:添加MyAdaptableJobFactory来手动注入

@Component("myAdaptableJobFactory") public class MyAdaptableJobFactory extends AdaptableJobFactory { //将一个对象加入到SpringIOC容器中,并且完成对象注入 @Autowired private AutowireCapableBeanFactory autowireCapableBeanFactory; /** * 将实列化的任务对象手动加入到SpringIOC容器中,并且完成对象注入 * @param bundle * @return * @throws Exception */ @Override protected Object createJobInstance(TriggerFiredBundle bundle) throws Exception { Object object = super.createJobInstance(bundle); //将object添加到SpringIOC容器中,并完成对象的注入 this.autowireCapableBeanFactory.autowireBean(object); return object; } }

四:修改QuartzConfig来完成配置

@Configuration public class QuartzConfig { /** * 创建Job对象 *要去做什么 */ @Bean public JobDetailFactoryBean jobDetailFactoryBean(){ JobDetailFactoryBean factory = new JobDetailFactoryBean(); /** * QuartzDemo 对象的实例化完全交给了JobDetailFactoryBean来完成 * 实际上实例化采用反射机制来实现 * QuartzDemo 的实例化没有经过Spring的处理 * Spring注入需要注入对象和被注入对象全部都存在与Spring IOC容器中 */ factory.setJobClass(QuartzDemo.class); return factory; } /** * 创建Trigger对象 * 什么时候去做 * 创建的简单的Trigger */ @Bean public SimpleTriggerFactoryBean simpleTriggerFactoryBean(JobDetailFactoryBean jobDetailFactoryBean){ SimpleTriggerFactoryBean factory = new SimpleTriggerFactoryBean(); //整合Job 关联Job // factory.setJobDetail(jobDetailFactoryBean.getObject()); //repeatInterval 执行的毫秒数 factory.setRepeatInterval(2000); //设置重复次数 factory.setRepeatCount(5); return factory; } /** * CronTrigger */ @Bean public CronTriggerFactoryBean cronTriggerFactoryBean(JobDetailFactoryBean jobDetailFactoryBean){ CronTriggerFactoryBean factory = new CronTriggerFactoryBean(); //关联Job factory.setJobDetail(jobDetailFactoryBean.getObject()); //设置CronTrigger factory.setCronExpression("0/2 * * * * ?"); return factory; } /** * 创建Scheduler对象 * 在什么时间去做什么事情 */ @Bean public SchedulerFactoryBean schedulerFactoryBean( SimpleTriggerFactoryBean simpleTriggerFactoryBean, MyAdaptableJobFactory myAdaptableJobFactory ){ SchedulerFactoryBean factory = new SchedulerFactoryBean(); //关联Trigger 可以关联CronTrigger factory.setTriggers(simpleTriggerFactoryBean.getObject()); //手动注入 //---------------------------------------------------------- factory.setJobFactory(myAdaptableJobFactory); //---------------------------------------------------------- return factory; } }

这样就完成了业务逻辑的定时触发

最新回复(0)