我正在尝试将 Quartz 2.2.1 与 Spring Boot 一起使用。我试图声明一个计划任务,该任务应该将一些数据写入文件中。我的工作定义如下:
public class JobTask implements Job {
@Autowired
JobController controller;
@Override
public void execute(JobExecutionContext arg0) throws JobExecutionException {
try {
controller.doPrintData();
} catch (Exception e) {
e.printStackTrace();
}
}
}
然后:
public class StartJob {
public static void main(final String[] args) {
final SchedulerFactory factory = new StdSchedulerFactory();
Scheduler scheduler;
try {
scheduler = factory.getScheduler();
scheduler.start();
} catch (SchedulerException e1) {
// TODO Auto-generated catch block
e1.printStackTrace();
}
try {
scheduler = factory.getScheduler();
final JobDetailImpl jobDetail = new JobDetailImpl();
jobDetail.setName("My job");
jobDetail.setJobClass(JobTask.class);
final SimpleTriggerImpl simpleTrigger = new SimpleTriggerImpl();
simpleTrigger.setStartTime(new Date(System.currentTimeMillis() + 5000));
//simpleTrigger.setStartTime(dateOf(12, 58, 00,06,05,2016));
simpleTrigger.setRepeatCount(SimpleTrigger.REPEAT_INDEFINITELY);
simpleTrigger.setRepeatInterval(5000);
simpleTrigger.setName("Trigger execution every 5 secondes");
scheduler.start();
scheduler.scheduleJob(jobDetail, simpleTrigger);
System.in.read();
if (scheduler != null) {
scheduler.shutdown();
}
} catch (final SchedulerException e) {
e.printStackTrace();
} catch (final IOException e) {
e.printStackTrace();
}
}
}
PS:我已经测试了我的控制器方法“doPrintData”并且它有效。但是当我把它放在执行方法中时,我面临着javaNullPointerException。
您需要使用 SpringBeanJobFactory 来使用 Spring 的自动装配 bean 创建 Job。
class AutowiringSpringBeanJobFactory extends SpringBeanJobFactory implements ApplicationContextAware {
private transient AutowireCapableBeanFactory beanFactory;
public void setApplicationContext(final ApplicationContext context) {
beanFactory = context.getAutowireCapableBeanFactory();
}
@Override
public Object createJobInstance(final TriggerFiredBundle bundle) throws Exception {
final Object job = super.createJobInstance(bundle);
beanFactory.autowireBean(job); //the magic is done here
return job;
}
}
然后当你这样做时
SchedulerFactory schedFact = new org.quartz.impl.StdSchedulerFactory();
scheduler = schedFact.getScheduler();
AutowiringSpringBeanJobFactory autowiringSpringBeanJobFactory = new AutowiringSpringBeanJobFactory();
autowiringSpringBeanJobFactory.setApplicationContext(applicationContext);
scheduler.setJobFactory(autowiringSpringBeanJobFactory);
Spring Boot 为您管理它。删除quartz依赖项并创建一个
Service
来安排执行:
@Service
public class JobScheduler{
@Autowired
JobController controller;
//Executes each 5000 ms
@Scheduled(fixedRate=5000)
public void performJob() {
controller.doPrintData();
}
}
并为您的应用程序启用任务调度:
@SpringBootApplication
@EnableScheduling
public class Application {
public static void main(String[] args) throws Exception {
SpringApplication.run(Application.class);
}
}
另见:
Kotlin 与 Quartz 解决方案
import org.quartz.spi.TriggerFiredBundle
import org.springframework.beans.factory.config.AutowireCapableBeanFactory
import org.springframework.scheduling.quartz.SpringBeanJobFactory
import org.springframework.stereotype.Component
@Component
class AutowiringSpringBeanJobFactory(
private val beanFactory: AutowireCapableBeanFactory
) : SpringBeanJobFactory() {
override fun createJobInstance(bundle: TriggerFiredBundle): Any {
val job = super.createJobInstance(bundle)
beanFactory.autowireBean(job)
return job
}
}
然后创建配置
import org.quartz.Scheduler
import org.springframework.boot.autoconfigure.quartz.QuartzProperties
import org.springframework.context.annotation.Bean
import org.springframework.context.annotation.Configuration
import org.springframework.scheduling.quartz.SchedulerFactoryBean
import java.util.Properties
import javax.sql.DataSource
@Configuration
class QuartzConfig(
private val dataSource: DataSource,
private val quartzProperties: QuartzProperties,
private val autowiringSpringBeanJobFactory: AutowiringSpringBeanJobFactory
) {
@Bean
fun schedulerFactoryBean(): SchedulerFactoryBean {
val schedulerFactoryBean = SchedulerFactoryBean()
schedulerFactoryBean.setDataSource(dataSource)
schedulerFactoryBean.setJobFactory(autowiringSpringBeanJobFactory)
val props = Properties()
quartzProperties.properties.forEach { (key, value) -> props.setProperty(key, value) }
schedulerFactoryBean.setQuartzProperties(props)
schedulerFactoryBean.afterPropertiesSet();
schedulerFactoryBean.setWaitForJobsToCompleteOnShutdown(true)
return schedulerFactoryBean
}
@Bean
fun scheduler(schedulerFactoryBean: SchedulerFactoryBean): Scheduler {
return schedulerFactoryBean.scheduler
}
}
现在您可以创建计划作业
JobBuilder.newJob(MyAutowiredJob::class.java)