Java Spring Quartz以编程方式触发作业
我有一个Sprint Boot-Java8应用程序,它有一个quartz作业,我在启动时配置它并设置一个时间表。作业将按照计划自动运行,正如您对quartz作业所期望的那样。但是,现在我希望能够允许用户通过点击前端的按钮手动触发这些作业,而不会扰乱该作业的正常调度。这是我所有的相关文件Java Spring Quartz以编程方式触发作业,java,spring,spring-boot,quartz-scheduler,javabeans,Java,Spring,Spring Boot,Quartz Scheduler,Javabeans,我有一个Sprint Boot-Java8应用程序,它有一个quartz作业,我在启动时配置它并设置一个时间表。作业将按照计划自动运行,正如您对quartz作业所期望的那样。但是,现在我希望能够允许用户通过点击前端的按钮手动触发这些作业,而不会扰乱该作业的正常调度。这是我所有的相关文件 application.yml quartz: fooCron: 0 0 1 * * ? fooGroup: foo-quartz-group QuartzConfig.java @Config
application.yml
quartz:
fooCron: 0 0 1 * * ?
fooGroup: foo-quartz-group
QuartzConfig.java
@Configuration
@ConfigurationProperties(prefix = "quartz")
public class QuartzConfig {
private String fooCron;
private String fooGroup;
@Autowired
private ApplicationContext applicationContext;
@Autowired
private PlatformTransactionManager transactionManager;
@Autowired
private DataSource dataSource;
@Bean
public SchedulerFactoryBean quartzScheduler() {
AutowiringSpringBeanJobFactory jobFactory = new AutowiringSpringBeanJobFactory();
jobFactory.setApplicationContext(applicationContext);
Trigger[] triggers = {fooTrigger().getObject()};
SchedulerFactoryBean quartzScheduler = new SchedulerFactoryBean();
quartzScheduler.setJobFactory(jobFactory);
quartzScheduler.setTransactionManager(transactionManager);
quartzScheduler.setDataSource(dataSource);
quartzScheduler.setOverwriteExistingJobs(true);
quartzScheduler.setSchedulerName("foo-scheduler");
quartzScheduler.setQuartzProperties(quartzProperties());
quartzScheduler.setTriggers(triggers);
return quartzScheduler;
}
@Bean
public CronTriggerFactoryBean fooTrigger() {
CronTriggerFactoryBean cronTriggerFactoryBean = new CronTriggerFactoryBean();
cronTriggerFactoryBean.setJobDetail(fooJob().getObject());
cronTriggerFactoryBean.setCronExpression(fooCron);
cronTriggerFactoryBean.setGroup(fooGroup);
return cronTriggerFactoryBean;
}
@Bean
public JobDetailFactoryBean fooJob() {
JobDetailFactoryBean jobDetailFactoryBean = new JobDetailFactoryBean();
jobDetailFactoryBean.setJobClass(FooJob.class);
jobDetailFactoryBean.setGroup(fooGroup);
jobDetailFactoryBean.setDurability(true);
return jobDetailFactoryBean;
}
@Bean
public Properties quartzProperties() {
PropertiesFactoryBean propertiesFactoryBean = new PropertiesFactoryBean();
propertiesFactoryBean.setLocation(new ClassPathResource("/quartz/quartz.properties"));
Properties properties = null;
try {
propertiesFactoryBean.afterPropertiesSet();
properties = propertiesFactoryBean.getObject();
} catch (IOException e) {
}
return properties;
}
//setters
}
@Service
public class FooJob implements Job {
private final FooRepository fooRepo; //This is a repository class annotated with @Repository.
public FooJob(FooRepository fooRepo) {
this.fooRepo = fooRepo;
}
@Override
public void execute(final JobExecutionContext context) throws JobExecutionException {
//do stuff
}
}
@RestController
@RequestMapping("/quartz")
public class QuartzController {
private SchedulerFactoryBean schedulerFactoryBean;
private Scheduler scheduler;
public DevopsController(final SchedulerFactoryBean quartzScheduler) {
this.schedulerFactoryBean = quartzScheduler;
scheduler = schedulerFactoryBean.getScheduler();
}
@PostMapping("/execute")
public ResponseEntity executeJob() {
HttpStatus status = OK;
try {
TriggerKey triggerKey = new TriggerKey("fooTrigger", "foo-quartz-group");
Trigger trigger = scheduler.getTrigger(triggerKey);
ScheduleBuilder scheduleBuilder = SimpleScheduleBuilder.simpleSchedule().withIntervalInSeconds(1).withRepeatCount(0);
JobDetail jobDetail = scheduler.getJobDetail(trigger.getJobKey());
Trigger newTrigger = TriggerBuilder.newTrigger()
.forJob(jobDetail)
.startNow()
.withIdentity(triggerKey)
.withSchedule(scheduleBuilder)
.startAt(Date.from(LocalDate.now().atStartOfDay().atZone(ZoneId.systemDefault()).toInstant()))
.build();
//I have tried all 3 of the following lines
scheduler.scheduleJob(jobDetail, new HashSet<>(Arrays.asList(trigger)), true);
//scheduler.addJob(jobDetail, true);
//scheduler.rescheduleJob(triggerKey, newTrigger);
} catch (SchedulerException e) {
status = BAD_REQUEST;
}
return new ResponseEntity<>(status);
}
}
FooJob.java
@Configuration
@ConfigurationProperties(prefix = "quartz")
public class QuartzConfig {
private String fooCron;
private String fooGroup;
@Autowired
private ApplicationContext applicationContext;
@Autowired
private PlatformTransactionManager transactionManager;
@Autowired
private DataSource dataSource;
@Bean
public SchedulerFactoryBean quartzScheduler() {
AutowiringSpringBeanJobFactory jobFactory = new AutowiringSpringBeanJobFactory();
jobFactory.setApplicationContext(applicationContext);
Trigger[] triggers = {fooTrigger().getObject()};
SchedulerFactoryBean quartzScheduler = new SchedulerFactoryBean();
quartzScheduler.setJobFactory(jobFactory);
quartzScheduler.setTransactionManager(transactionManager);
quartzScheduler.setDataSource(dataSource);
quartzScheduler.setOverwriteExistingJobs(true);
quartzScheduler.setSchedulerName("foo-scheduler");
quartzScheduler.setQuartzProperties(quartzProperties());
quartzScheduler.setTriggers(triggers);
return quartzScheduler;
}
@Bean
public CronTriggerFactoryBean fooTrigger() {
CronTriggerFactoryBean cronTriggerFactoryBean = new CronTriggerFactoryBean();
cronTriggerFactoryBean.setJobDetail(fooJob().getObject());
cronTriggerFactoryBean.setCronExpression(fooCron);
cronTriggerFactoryBean.setGroup(fooGroup);
return cronTriggerFactoryBean;
}
@Bean
public JobDetailFactoryBean fooJob() {
JobDetailFactoryBean jobDetailFactoryBean = new JobDetailFactoryBean();
jobDetailFactoryBean.setJobClass(FooJob.class);
jobDetailFactoryBean.setGroup(fooGroup);
jobDetailFactoryBean.setDurability(true);
return jobDetailFactoryBean;
}
@Bean
public Properties quartzProperties() {
PropertiesFactoryBean propertiesFactoryBean = new PropertiesFactoryBean();
propertiesFactoryBean.setLocation(new ClassPathResource("/quartz/quartz.properties"));
Properties properties = null;
try {
propertiesFactoryBean.afterPropertiesSet();
properties = propertiesFactoryBean.getObject();
} catch (IOException e) {
}
return properties;
}
//setters
}
@Service
public class FooJob implements Job {
private final FooRepository fooRepo; //This is a repository class annotated with @Repository.
public FooJob(FooRepository fooRepo) {
this.fooRepo = fooRepo;
}
@Override
public void execute(final JobExecutionContext context) throws JobExecutionException {
//do stuff
}
}
@RestController
@RequestMapping("/quartz")
public class QuartzController {
private SchedulerFactoryBean schedulerFactoryBean;
private Scheduler scheduler;
public DevopsController(final SchedulerFactoryBean quartzScheduler) {
this.schedulerFactoryBean = quartzScheduler;
scheduler = schedulerFactoryBean.getScheduler();
}
@PostMapping("/execute")
public ResponseEntity executeJob() {
HttpStatus status = OK;
try {
TriggerKey triggerKey = new TriggerKey("fooTrigger", "foo-quartz-group");
Trigger trigger = scheduler.getTrigger(triggerKey);
ScheduleBuilder scheduleBuilder = SimpleScheduleBuilder.simpleSchedule().withIntervalInSeconds(1).withRepeatCount(0);
JobDetail jobDetail = scheduler.getJobDetail(trigger.getJobKey());
Trigger newTrigger = TriggerBuilder.newTrigger()
.forJob(jobDetail)
.startNow()
.withIdentity(triggerKey)
.withSchedule(scheduleBuilder)
.startAt(Date.from(LocalDate.now().atStartOfDay().atZone(ZoneId.systemDefault()).toInstant()))
.build();
//I have tried all 3 of the following lines
scheduler.scheduleJob(jobDetail, new HashSet<>(Arrays.asList(trigger)), true);
//scheduler.addJob(jobDetail, true);
//scheduler.rescheduleJob(triggerKey, newTrigger);
} catch (SchedulerException e) {
status = BAD_REQUEST;
}
return new ResponseEntity<>(status);
}
}
现在,这运行只是一个有趣的定时计划。根据yml文件中的cron配置,0 0 1**?
,作业每天凌晨1点执行。伟大的但是现在我想手动执行这个。因此,我构建了一个控制器来接收来自UI的手动触发请求
QuartzController.java
@Configuration
@ConfigurationProperties(prefix = "quartz")
public class QuartzConfig {
private String fooCron;
private String fooGroup;
@Autowired
private ApplicationContext applicationContext;
@Autowired
private PlatformTransactionManager transactionManager;
@Autowired
private DataSource dataSource;
@Bean
public SchedulerFactoryBean quartzScheduler() {
AutowiringSpringBeanJobFactory jobFactory = new AutowiringSpringBeanJobFactory();
jobFactory.setApplicationContext(applicationContext);
Trigger[] triggers = {fooTrigger().getObject()};
SchedulerFactoryBean quartzScheduler = new SchedulerFactoryBean();
quartzScheduler.setJobFactory(jobFactory);
quartzScheduler.setTransactionManager(transactionManager);
quartzScheduler.setDataSource(dataSource);
quartzScheduler.setOverwriteExistingJobs(true);
quartzScheduler.setSchedulerName("foo-scheduler");
quartzScheduler.setQuartzProperties(quartzProperties());
quartzScheduler.setTriggers(triggers);
return quartzScheduler;
}
@Bean
public CronTriggerFactoryBean fooTrigger() {
CronTriggerFactoryBean cronTriggerFactoryBean = new CronTriggerFactoryBean();
cronTriggerFactoryBean.setJobDetail(fooJob().getObject());
cronTriggerFactoryBean.setCronExpression(fooCron);
cronTriggerFactoryBean.setGroup(fooGroup);
return cronTriggerFactoryBean;
}
@Bean
public JobDetailFactoryBean fooJob() {
JobDetailFactoryBean jobDetailFactoryBean = new JobDetailFactoryBean();
jobDetailFactoryBean.setJobClass(FooJob.class);
jobDetailFactoryBean.setGroup(fooGroup);
jobDetailFactoryBean.setDurability(true);
return jobDetailFactoryBean;
}
@Bean
public Properties quartzProperties() {
PropertiesFactoryBean propertiesFactoryBean = new PropertiesFactoryBean();
propertiesFactoryBean.setLocation(new ClassPathResource("/quartz/quartz.properties"));
Properties properties = null;
try {
propertiesFactoryBean.afterPropertiesSet();
properties = propertiesFactoryBean.getObject();
} catch (IOException e) {
}
return properties;
}
//setters
}
@Service
public class FooJob implements Job {
private final FooRepository fooRepo; //This is a repository class annotated with @Repository.
public FooJob(FooRepository fooRepo) {
this.fooRepo = fooRepo;
}
@Override
public void execute(final JobExecutionContext context) throws JobExecutionException {
//do stuff
}
}
@RestController
@RequestMapping("/quartz")
public class QuartzController {
private SchedulerFactoryBean schedulerFactoryBean;
private Scheduler scheduler;
public DevopsController(final SchedulerFactoryBean quartzScheduler) {
this.schedulerFactoryBean = quartzScheduler;
scheduler = schedulerFactoryBean.getScheduler();
}
@PostMapping("/execute")
public ResponseEntity executeJob() {
HttpStatus status = OK;
try {
TriggerKey triggerKey = new TriggerKey("fooTrigger", "foo-quartz-group");
Trigger trigger = scheduler.getTrigger(triggerKey);
ScheduleBuilder scheduleBuilder = SimpleScheduleBuilder.simpleSchedule().withIntervalInSeconds(1).withRepeatCount(0);
JobDetail jobDetail = scheduler.getJobDetail(trigger.getJobKey());
Trigger newTrigger = TriggerBuilder.newTrigger()
.forJob(jobDetail)
.startNow()
.withIdentity(triggerKey)
.withSchedule(scheduleBuilder)
.startAt(Date.from(LocalDate.now().atStartOfDay().atZone(ZoneId.systemDefault()).toInstant()))
.build();
//I have tried all 3 of the following lines
scheduler.scheduleJob(jobDetail, new HashSet<>(Arrays.asList(trigger)), true);
//scheduler.addJob(jobDetail, true);
//scheduler.rescheduleJob(triggerKey, newTrigger);
} catch (SchedulerException e) {
status = BAD_REQUEST;
}
return new ResponseEntity<>(status);
}
}
我到底做错了什么?如何使此作业按照计划自动运行,但也在手动请求时执行
我使用的是sprint boot1.5.9.RELEASE
和quartz2.2.1
正如前面所说,您必须在FooJob
中添加一个无参数构造函数。您的方法的问题是,您将无法以这种方式获得foodrepository
public FooJob() {
}
你有两个选择
1) 如果FooRepository
具有@Respository注释,则可以将@Autowired注释添加到构造函数中
@Autowired
public FooJob(FooRepository fooRepo) {
this.fooRepo = fooRepo;
}
由于您有了@Repository注释,Spring将注意到它可以创建所需对象的实例来创建@服务的实例
2) 您可以添加一个配置类
@Configuration
public class Config {}
您必须在那里创建一个服务实例(FooJob
)
依我拙见,第一种选择看起来更好
让我知道它是否有效 如前所述,您必须在FooJob
中添加一个无参数构造函数。您的方法的问题是,您将无法以这种方式获得foodrepository
public FooJob() {
}
你有两个选择
1) 如果FooRepository
具有@Respository注释,则可以将@Autowired注释添加到构造函数中
@Autowired
public FooJob(FooRepository fooRepo) {
this.fooRepo = fooRepo;
}
由于您有了@Repository注释,Spring将注意到它可以创建所需对象的实例来创建@服务的实例
2) 您可以添加一个配置类
@Configuration
public class Config {}
您必须在那里创建一个服务实例(FooJob
)
依我拙见,第一种选择看起来更好
让我知道它是否有效 java.lang.NoSuchMethodException:com.test.jobs.FooJob.()constructor@Richardisscheduler.triggerJob(JobKey.JobKey(“您的作业密钥”)代码>代码不够?java.lang.NoSuchMethodException:com.test.jobs.FooJob。(
是您没有“否”参数constructor@Richardisscheduler.triggerJob(JobKey.JobKey(“您的作业密钥”)代码>代码不够?