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 when

Schedule 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

@Component

public 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的ThreadPoolTask​​Scheduler,该代码已大大简化并且可以按预期工作。

回答:

SpringBeanAutowiringSupport使用Web应用程序上下文,在您的情况下不可用。如果需要在石英中使用弹簧管理的豆,则应使用spring提供的石英支架。这将为您提供对所有托管Bean的完全访问权限。有关更多信息,请参见http://docs.spring.io/spring/docs/current/spring-

framework-

reference/html/scheduling.html上spring

docs的石英部分。另请参见下面的示例,将石英与弹簧托管的豆一起使用。示例基于您的代码。因此,您可以使用以下替代弹簧来更改第一个代码段(完成石英初始化)。

创建工作细节工厂

@Component

public 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();

}

}

创建触发器工厂

@Component

public 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

@Component

public 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

回到顶部