在 Spring Boot 中部署 Quartz 时出现 NullPointerException

问题描述 投票:0回答:3

我正在尝试将 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

java spring-boot quartz-scheduler
3个回答
5
投票

您需要使用 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);

3
投票

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);
    }
}

另见:


0
投票

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)
© www.soinside.com 2019 - 2024. All rights reserved.