我试着在春天使用石英调度程序。配置多个作业时,我得到以下异常
Job2中方法jobTrigger的参数0需要一个无法找到的类型为'org.quartz.JobDetail'的bean。
quartz - v2.3,Spring - v4.2.x
配置类
127.0.0.1 testapp.yourdomain.com
SpringBeanJobFactory
proxy revers
}
工作1
@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;
}
工作2
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;
}
Service类有Spring JPA repos。 问题的根本原因是以下自动服务。如果我从两个作业中删除以下自动装配的服务,它可以正常工作。
@Autowired 私人服务;
如果这个自动装配的bean只有一个作业,那么没有例外。 如何使用相同的自动连接依赖项配置多个作业? 造成这个问题的原因是什么?
答案 0 :(得分:2)
这是您在一个配置文件中处理多个Quartz作业时引用的http://www.baeldung.com/spring-quartz-schedule的修改版本。为简洁起见,我不包括整个QrtzSheduler类只是替换调度器方法和在触发器中使用@Qualifier引用:
...
@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) {
...
}
答案 1 :(得分:0)
jobTrigger
方法期望参数JobDetail
,但传递的bean类型为JobDetailFactoryBean
。
也许你应该做出以下改变或类似的事情。
@Bean(name = "jobBean1")
public JobDetail job() {
return SchedulerConfig.createJobDetail(this.getClass()).getObject();
}
对于job2也一样。
顺便说一下, 你提到Spring - v1.5。您实际使用的是哪个版本的Spring?答案 2 :(得分:0)
您正尝试在Spring 4.2中使用Spring启动配置。
尝试在Job类中更改以下方法,如下所示
var set of 1..100: y:: output_var;
也需要使用弹簧4.3,因为你需要
@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();
}
我相信Collection Autowire仅适用于4.3
答案 3 :(得分:0)
我遇到了同样的问题,经过一番挣扎后我才能解决它。它可能适用于作业类中使用的注释。我看到你正在使用@Component
,就像我的情况一样。而石英调度程序配置则使用@Configuration
标记进行注释。
解决方案是使用@Configuration
标记为您的作业添加注释。我的猜测是@Bean
注释类中构造的@Component
在初始化@Configuration
注释的阶段中不是完整的构造/映射。
答案 4 :(得分:0)
我遇到了同样的问题,但现在已经解决
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;
}
此后执行job class。您可以使用自动接线
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());
}
}
}