springboot 集成 quartz 定时任务 Job类中注入的bean为null 的具体解决办法及代码
时间: 2024-03-27 09:34:59 浏览: 132
当在 Job 类中注入 Spring Bean 时,需要使用 Spring 提供的 JobFactory 来创建 Job 实例,这样 Job 类中的 Bean 才能被正确注入。具体实现步骤如下:
1. 创建一个实现了 Spring 的 JobFactory 接口的类,用于创建 Job 实例。
```java
import org.quartz.Job;
import org.quartz.Scheduler;
import org.quartz.SchedulerContext;
import org.quartz.spi.JobFactory;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.context.ApplicationContext;
import org.springframework.stereotype.Component;
@Component
public class AutowiringSpringBeanJobFactory implements JobFactory {
@Autowired
private ApplicationContext context;
/**
* {@inheritDoc}
*/
@Override
public Job newJob(TriggerFiredBundle bundle, Scheduler scheduler) throws SchedulerException {
final Job job = (Job) context.getBean(bundle.getJobDetail().getJobClass());
final SchedulerContext schedulerContext = scheduler.getContext();
schedulerContext.put("applicationContext", context);
return job;
}
}
```
2. 在 Quartz 配置中注册 JobFactory,如下所示:
```java
import javax.sql.DataSource;
import org.quartz.JobDetail;
import org.quartz.Scheduler;
import org.quartz.Trigger;
import org.quartz.impl.StdSchedulerFactory;
import org.quartz.impl.jdbcjobstore.JobStoreTX;
import org.quartz.impl.jdbcjobstore.PostgreSQLDelegate;
import org.quartz.impl.jdbcjobstore.StdJDBCDelegate;
import org.quartz.impl.jdbcjobstore.StdJDBCJobStore;
import org.quartz.impl.jdbcjobstore.oracle.OracleDelegate;
import org.quartz.spi.JobFactory;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.beans.factory.annotation.Qualifier;
import org.springframework.context.ApplicationContext;
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;
import org.springframework.core.env.Environment;
@Configuration
public class QuartzConfig {
@Autowired
private Environment env;
@Bean
public JobFactory jobFactory(ApplicationContext applicationContext) {
AutowiringSpringBeanJobFactory jobFactory = new AutowiringSpringBeanJobFactory();
jobFactory.setApplicationContext(applicationContext);
return jobFactory;
}
@Bean
public Scheduler scheduler(Trigger[] triggers, @Qualifier("quartzDataSource") DataSource dataSource) throws SchedulerException {
StdSchedulerFactory factory = new StdSchedulerFactory();
factory.initialize(quartzProperties());
Scheduler scheduler = factory.getScheduler();
scheduler.setJobFactory(jobFactory);
scheduler.setDataSource(dataSource);
scheduler.setQuartzProperties(quartzProperties());
scheduler.start();
for (Trigger trigger : triggers) {
scheduler.scheduleJob(trigger.getJobDetail(), trigger);
}
return scheduler;
}
@Bean
public JobDetail jobDetail() {
return JobBuilder.newJob().ofType(MyJob.class)
.storeDurably().withIdentity("MyJob").withDescription("Invoke My Job service...").build();
}
@Bean
public Trigger trigger(JobDetail job) {
return TriggerBuilder.newTrigger().forJob(job)
.withIdentity("MyJobTrigger").withDescription("My Job trigger").withSchedule(CronScheduleBuilder.cronSchedule(env.getProperty("myjob.cron.expression"))).build();
}
@Bean
public Properties quartzProperties() {
Properties properties = new Properties();
properties.setProperty(StdSchedulerFactory.PROP_SCHED_INSTANCE_NAME, env.getProperty("scheduler.instance.name"));
properties.setProperty(StdSchedulerFactory.PROP_SCHED_INSTANCE_ID, env.getProperty("scheduler.instance.id"));
properties.setProperty(StdSchedulerFactory.PROP_THREAD_POOL_CLASS, env.getProperty("scheduler.threadPool.class"));
properties.setProperty(StdSchedulerFactory.PROP_THREAD_POOL_THREAD_COUNT, env.getProperty("scheduler.threadPool.threadCount"));
properties.setProperty(StdSchedulerFactory.PROP_JOB_STORE_CLASS, env.getProperty("scheduler.jobStore.class"));
properties.setProperty(StdSchedulerFactory.PROP_JOB_STORE_DRIVER_DELEGATE_CLASS, env.getProperty("scheduler.jobStore.driverDelegateClass"));
properties.setProperty(StdSchedulerFactory.PROP_JOB_STORE_USE_PROPERTIES, env.getProperty("scheduler.jobStore.useProperties"));
properties.setProperty(StdSchedulerFactory.PROP_JOB_STORE_DATASOURCE, env.getProperty("scheduler.jobStore.dataSource"));
properties.setProperty(StdSchedulerFactory.PROP_JOB_STORE_TABLE_PREFIX, env.getProperty("scheduler.jobStore.tablePrefix"));
properties.setProperty(StdSchedulerFactory.PROP_JOB_STORE_IS_CLUSTERED, env.getProperty("scheduler.jobStore.isClustered"));
properties.setProperty(StdSchedulerFactory.PROP_JOB_STORE_CLUSTER_CHECKIN_INTERVAL, env.getProperty("scheduler.jobStore.clusterCheckinInterval"));
properties.setProperty(StdSchedulerFactory.PROP_JOB_STORE_MAX_MISFIRES_TO_HANDLE_AT_A_TIME, env.getProperty("scheduler.jobStore.maxMisfiresToHandleAtATime"));
properties.setProperty(StdSchedulerFactory.PROP_JOB_STORE_MISFIRE_THRESHOLD, env.getProperty("scheduler.jobStore.misfireThreshold"));
return properties;
}
}
```
3. 在 Job 类中注入 Bean,如下所示:
```java
import org.quartz.Job;
import org.quartz.JobExecutionContext;
import org.quartz.JobExecutionException;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.context.ApplicationContext;
import org.springframework.stereotype.Component;
@Component
public class MyJob implements Job {
@Autowired
private MyService myService;
/**
* {@inheritDoc}
*/
@Override
public void execute(JobExecutionContext context) throws JobExecutionException {
ApplicationContext applicationContext = (ApplicationContext) context.getScheduler().getContext().get("applicationContext");
applicationContext.getAutowireCapableBeanFactory().autowireBean(this);
myService.doSomething();
}
}
```
通过这种方式,就可以在 Quartz 的 Job 类中注入 Spring Bean。
阅读全文