我尝试在春季使用石英调度程序。配置多个作业
时,我会以下异常Job 2中的方法jobtrigger的参数0需要一个找不到的bean org.quartz.jobdetail'。
Quartz -V2.3,Spring -V4.2.x
配置类
@Configuration
public class SchedulerConfig {
private static final Logger LOG = LoggerFactory.getLogger(SchedulerConfig.class);
@Autowired
List<Trigger> triggers;
@Bean
public JobFactory jobFactory(ApplicationContext applicationContext) {
AutowiringSpringBeanJobFactory jobFactory = new AutowiringSpringBeanJobFactory();
jobFactory.setApplicationContext(applicationContext);
return jobFactory;
}
@Bean
public SchedulerFactoryBean schedulerFactoryBean(JobFactory jobFactory) throws IOException {
SchedulerFactoryBean factory = new SchedulerFactoryBean();
factory.setAutoStartup(true);
factory.setJobFactory(jobFactory);
factory.setQuartzProperties(quartzProperties());
if (triggers != null && !triggers.isEmpty()) {
LOG.info("starting jobs... Total Triggers - " + triggers.size());
factory.setTriggers(triggers.toArray(new Trigger[triggers.size()]));
}
return factory;
}
@Bean
public Properties quartzProperties() throws IOException {
PropertiesFactoryBean propertiesFactoryBean = new PropertiesFactoryBean();
propertiesFactoryBean.setLocation(new ClassPathResource("/quartz.properties"));
propertiesFactoryBean.afterPropertiesSet();
return propertiesFactoryBean.getObject();
}
public static CronTriggerFactoryBean createCronTrigger(JobDetail jobDetail, String cronExpression) {
CronTriggerFactoryBean factoryBean = new CronTriggerFactoryBean();
factoryBean.setJobDetail(jobDetail);
factoryBean.setCronExpression(cronExpression);
factoryBean.setMisfireInstruction(SimpleTrigger.MISFIRE_INSTRUCTION_FIRE_NOW);
return factoryBean;
}
public static JobDetailFactoryBean createJobDetail(Class jobClass) {
JobDetailFactoryBean factoryBean = new JobDetailFactoryBean();
factoryBean.setJobClass(jobClass);
factoryBean.setDurability(true);
return factoryBean;
}
springbeanjobfactory
public final class AutowiringSpringBeanJobFactory extends SpringBeanJobFactory implements ApplicationContextAware {
private static final Logger LOG = LoggerFactory.getLogger(AutowiringSpringBeanJobFactory.class);
private transient AutowireCapableBeanFactory beanFactory;
@Override
public void setApplicationContext(final ApplicationContext context) {
beanFactory = context.getAutowireCapableBeanFactory();
}
@Override
protected Object createJobInstance(final TriggerFiredBundle bundle) throws Exception {
final Object job = super.createJobInstance(bundle);
LOG.info("create job instance");
beanFactory.autowireBean(job);
return job;
}
}
作业1
@Component
@DisallowConcurrentExecution
public class Job1 implements Job {
private final Logger log = LoggerFactory.getLogger(this.getClass());
@Value("${schedule}")
private String frequency;
@Autowired
private Service service;
@Override
public void execute(JobExecutionContext jobExecutionContext) {
log.info("execute");
}
@Bean(name = "jobBean1")
public JobDetailFactoryBean job() {
return SchedulerConfig.createJobDetail(this.getClass());
}
@Bean(name = "jobBean1Trigger")
public CronTriggerFactoryBean jobTrigger(@Qualifier("jobBean1")JobDetail jobDetail) {
return SchedulerConfig.createCronTrigger(jobDetail, frequency);
}
作业2
@Component
@DisallowConcurrentExecution
public class Job2 implements Job {
private final Logger log = LoggerFactory.getLogger(this.getClass());
@Value("${schedule}")
private String frequency;
@Autowired
private Service service;
@Override
public void execute(JobExecutionContext jobExecutionContext) {
log.info("execute");
}
@Bean(name = "jobBean2")
public JobDetailFactoryBean job() {
return SchedulerConfig.createJobDetail(this.getClass());
}
@Bean(name = "jobBean2Trigger")
public CronTriggerFactoryBean jobTrigger(@Qualifier("jobBean2")JobDetail jobDetail) {
return SchedulerConfig.createCronTrigger(jobDetail, frequency);
}
服务类具有Spring JPA存储库。问题的根本原因是下面的自动服务。如果我从两个工作中删除以下自动服务的服务,则可以正常工作。
@autowired 私人服务服务;
如果此自动豆只有一项作业,则没有例外。如何使用相同的自动依赖性配置多个作业?什么原因是这个问题?
这是http://www.baeldung.com/spring-quartz-schedule的修改版本,您在一个配置文件中处理多个石英作业。简而
...
@Bean
public Scheduler scheduler(Map<String, JobDetail> jobMap, Set<? extends Trigger> triggers) throws SchedulerException, IOException {
StdSchedulerFactory factory = new StdSchedulerFactory();
factory.initialize(new ClassPathResource("quartz.properties").getInputStream());
logger.debug("Getting a handle to the Scheduler");
Scheduler scheduler = factory.getScheduler();
scheduler.setJobFactory(springBeanJobFactory());
Map<JobDetail,Set<? extends Trigger>> triggersAndJobs = new HashMap<JobDetail,Set<? extends Trigger>>;
for(JobDetail jobDetail : jobMap.getValues()){
for(Trigger trigger : triggers){
if(trigger.getJobKey().equals(jobDetail.getKey())){
Set<Trigger> set = new HashSet<>();
set.add(trigger);
triggerAndJobs.put(jobDetail,set);
}
}
}
scheduler.scheduleJobs(triggersAndJobs, false);
logger.debug("Starting Scheduler threads");
scheduler.start();
return scheduler;
}
@Bean(name="jobOne")
public JobDetail jobDetailOne() {
...
}
@Bean(name="jobTwo")
public JobDetail jobDetailTwo() {
...
}
@Bean
public Trigger triggerOne(@Qualifier("jobOne")JobDetail jobDetail) {
...
}
@Bean
public Trigger triggerTwo(@Qualifier("jobTwo")JobDetail jobDetail) {
...
}
您正在尝试使用Spring Boot配置使用Spring 4.2。
尝试更改作业类内的以下方法
@Bean(name = "jobBean1")
public JobDetail job() {
return SchedulerConfig.createJobDetail(this.getClass()).getObject();
}
@Bean(name = "jobBean1Trigger")
public CronTrigger jobTrigger(@Qualifier("jobBean1")JobDetail jobDetail) {
return SchedulerConfig.createCronTrigger(jobDetail, frequency).getObject();
}
也使用弹簧4.3,因为您需要
@Autowired
List<Trigger> triggers;
我相信Collection Autowire仅在4.3
我遇到了同样的问题,经过一些挣扎,我就能解决它。这可能是在工作类中使用的注释。我看到您正在使用@Component
,就像我的情况下一样。而是用@Configuration
标签注释的石英调度程序配置。
解决方案是用@Configuration
标签注释您的作业。我的猜测是,在@Component
注释的类中构建的@Bean
的s并未在初始化@Configuration
注释的阶段构造/映射。
我也有同样的问题,但是现在解决了
package com.crif.credity.config;
import org.quartz.spi.TriggerFiredBundle;
import org.springframework.beans.factory.config.AutowireCapableBeanFactory;
import org.springframework.context.ApplicationContext;
import org.springframework.context.ApplicationContextAware;
import org.springframework.scheduling.quartz.SpringBeanJobFactory;
public class SchedulerJobFactory extends SpringBeanJobFactory implements ApplicationContextAware {
private AutowireCapableBeanFactory beanFacotry;
@Override
protected Object createJobInstance(TriggerFiredBundle triggerBundle) throws Exception {
Object createJobInstance = super.createJobInstance(triggerBundle);
beanFacotry.autowireBean(createJobInstance);
return createJobInstance;
}
@Override
public void setApplicationContext(ApplicationContext applicationContext) {
beanFacotry = applicationContext.getAutowireCapableBeanFactory();
}
}
在配置Java文件中,您可以在bean下方创建
@Autowired
private ApplicationContext applicationContext;
/** The data source. */
@Bean
public SchedulerFactoryBean schedulerFactoryBean() throws IOException {
SchedulerJobFactory jobFactory = new SchedulerJobFactory();
jobFactory.setApplicationContext(applicationContext);
SchedulerFactoryBean factoryBean = new SchedulerFactoryBean();
factoryBean.setOverwriteExistingJobs(true);
factoryBean.setJobFactory(jobFactory);
return factoryBean;
}
在实施工作类别之后。您可以使用自动
package com.crif.credity.jobs;
public class Test implements Job {
@Autowired
private BatchClientService batchClientService;
@Override
public void execute(JobExecutionContext context) throws JobExecutionException{
try {
batchClientService.executeJob(CredityJob.NEWSCHECK, instanceId);
} catch (Exception ex) {
LOG.info(ex.getMessage());
}
}
}