Spring Boot:在Quartz作业执行中使用@Service
在一个应用程序中,由于我将其从经典的Spring Web应用程序(在系统Tomcat中部署)转换为Spring
Boot(V1.2.1)应用程序,因此面临基于Quartz的计划作业不再工作的问题。
我安排这些Quartz作业是这样的:
// My own Schedule object which holds data about what to schedule whenSchedule schedule = scheduleService.get(id of the schedule);
String scheduleId = schedule.getId();
JobKey jobKey = new JobKey(scheduleId);
TriggerKey triggerKey = new TriggerKey(scheduleId);
JobDataMap jobData = new JobDataMap();
jobData.put("scheduleId", scheduleId);
JobBuilder jobBuilder = JobBuilder.newJob(ScheduledActionRunner.class)
.withIdentity(jobKey)
.withDescription(schedule.getName())
.usingJobData(jobData);
JobDetail job = jobBuilder.build();
TriggerBuilder triggerBuilder = TriggerBuilder.newTrigger()
.forJob(jobKey)
.withIdentity(triggerKey)
.withDescription(schedule.getName());
triggerBuilder = triggerBuilder.withSchedule(CronScheduleBuilder.cronSchedule(schedule.toCronExpression()));
Trigger trigger = triggerBuilder.build();
org.quartz.Scheduler scheduler = schedulerFactoryBean.getScheduler();
scheduler.scheduleJob(job, trigger);
ScheduledActionRunner
:
@Componentpublic class ScheduledActionRunner extends QuartzJobBean {
@Autowired
private ScheduleService scheduleService;
public ScheduledActionRunner() {
}
@Override
public void executeInternal(final JobExecutionContext context) throws JobExecutionException {
SpringBeanAutowiringSupport.processInjectionBasedOnCurrentContext(this);
final JobDataMap jobDataMap = context.getMergedJobDataMap();
final String scheduleId = jobDataMap.getString("scheduleId");
final Schedule schedule = scheduleService.get(scheduleId);
// here it goes BANG since scheduleService is null
}
}
ScheduleService
是一种经典的Spring服务,可从Hibernate中获取数据。就像我在上面说的那样,在我移到Spring
Boot之前,这一直很好。
当我用经典的Spring应用程序实现此代码时SpringBeanAutowiringSupport.processInjectionBasedOnCurrentContext(this);
,巧妙地完成了自动装配服务的工作。
在Spring Boot环境中再次进行这项工作需要什么?
最后,我选择不再使用Quartz而是使用Spring的ThreadPoolTaskScheduler,该代码已大大简化并且可以按预期工作。
回答:
SpringBeanAutowiringSupport使用Web应用程序上下文,在您的情况下不可用。如果需要在石英中使用弹簧管理的豆,则应使用spring提供的石英支架。这将为您提供对所有托管Bean的完全访问权限。有关更多信息,请参见http://docs.spring.io/spring/docs/current/spring-
framework-
reference/html/scheduling.html上spring
docs的石英部分。另请参见下面的示例,将石英与弹簧托管的豆一起使用。示例基于您的代码。因此,您可以使用以下替代弹簧来更改第一个代码段(完成石英初始化)。
创建工作细节工厂
@Componentpublic class ScheduledActionRunnerJobDetailFactory extends JobDetailFactoryBean {
@Autowired
private ScheduleService scheduleService;
@Override
public void afterPropertiesSet() {
setJobClass(ScheduledActionRunner.class);
Map<String, Object> data = new HashMap<String, Object>();
data.put("scheduleService", scheduleService);
setJobDataAsMap(data);
super.afterPropertiesSet();
}
}
创建触发器工厂
@Componentpublic class ActionCronTriggerFactoryBean extends CronTriggerFactoryBean {
@Autowired
private ScheduledActionRunnerJobDetailFactory jobDetailFactory;
@Value("${cron.pattern}")
private String pattern;
@Override
public void afterPropertiesSet() throws ParseException {
setCronExpression(pattern);
setJobDetail(jobDetailFactory.getObject());
super.afterPropertiesSet();
}
}
最后创建SchedulerFactory
@Componentpublic class ActionSchedulerFactoryBean extends SchedulerFactoryBean {
@Autowired
private ScheduledActionRunnerJobDetailFactory jobDetailFactory;
@Autowired
private ActionCronTriggerFactoryBean triggerFactory;
@Override
public void afterPropertiesSet() throws Exception {
setJobDetails(jobDetailFactory.getObject());
setTriggers(triggerFactory.getObject());
super.afterPropertiesSet();
}
}
以上是 Spring Boot:在Quartz作业执行中使用@Service 的全部内容, 来源链接: utcz.com/qa/409750.html