Java Spring Quartz使用父类构造函数设置基于构造函数的注入
我有一个SpringBoot项目,我想使用quartz在特定时间运行特定作业。我有这样的课堂布局:Java Spring Quartz使用父类构造函数设置基于构造函数的注入,java,spring,dependency-injection,quartz-scheduler,quartz,Java,Spring,Dependency Injection,Quartz Scheduler,Quartz,我有一个SpringBoot项目,我想使用quartz在特定时间运行特定作业。我有这样的课堂布局: abstract public class AbstractFoo { protected final FooB fooB; public AbstractFoo(FooB fooB) { this.fooB = fooB; } } @Service public class SomeJob extends AbstractFoo implements
abstract public class AbstractFoo {
protected final FooB fooB;
public AbstractFoo(FooB fooB) {
this.fooB = fooB;
}
}
@Service
public class SomeJob extends AbstractFoo implements Job {
public SomeJob(FooB fooB) {
super(fooB);
}
@Override
public void execute(final JobExecutionContext context) throws JobExecutionException {
//do stuff
}
}
但是,当我运行此作业时,会出现以下错误:
2017-12-06 14:18:01,383 ERROR --- [quartz-jobs] org.quartz.core.ErrorLogger : An error occured instantiating job to be executed. job= 'jobGroup.someJob'
org.quartz.SchedulerException: Job instantiation failed
at org.springframework.scheduling.quartz.AdaptableJobFactory.newJob(AdaptableJobFactory.java:45)
at org.quartz.core.JobRunShell.initialize(JobRunShell.java:127)
at org.quartz.core.QuartzSchedulerThread.run(QuartzSchedulerThread.java:375)
Caused by: java.lang.InstantiationException: com.jobs.SomeJob
at java.lang.Class.newInstance(Class.java:427)
at org.springframework.scheduling.quartz.AdaptableJobFactory.createJobInstance(AdaptableJobFactory.java:58)
at org.springframework.scheduling.quartz.SpringBeanJobFactory.createJobInstance(SpringBeanJobFactory.java:74)
at com.config.AutowiringSpringBeanJobFactory.createJobInstance(AutowiringSpringBeanJobFactory.java:27)
at org.springframework.scheduling.quartz.AdaptableJobFactory.newJob(AdaptableJobFactory.java:41)
... 2 common frames omitted
Caused by: java.lang.NoSuchMethodException: com.jobs.SomeJob.<init>()
at java.lang.Class.getConstructor0(Class.java:3082)
at java.lang.Class.newInstance(Class.java:412)
... 6 common frames omitted
这是我的石英配置:
@Configuration
public class QuartzConfig {
@Autowired
private DataSource dataSource;
@Autowired
private PlatformTransactionManager transactionManager;
@Autowired
private ApplicationContext applicationContext;
@Bean
public SchedulerFactoryBean quartzScheduler() {
SchedulerFactoryBean quartzScheduler = new SchedulerFactoryBean();
quartzScheduler.setDataSource(dataSource);
quartzScheduler.setTransactionManager(transactionManager);
quartzScheduler.setOverwriteExistingJobs(true);
quartzScheduler.setSchedulerName("quartz-jobs");
AutowiringSpringBeanJobFactory jobFactory = new AutowiringSpringBeanJobFactory();
jobFactory.setApplicationContext(applicationContext);
quartzScheduler.setJobFactory(jobFactory);
quartzScheduler.setQuartzProperties(quartzProperties());
Trigger[] triggers = {someJobTrigger().getObject();
quartzScheduler.setTriggers(triggers);
return quartzScheduler;
}
@Bean
public CronTriggerFactoryBean someJobTrigger() {
CronTriggerFactoryBean cronTriggerFactoryBean = new CronTriggerFactoryBean();
cronTriggerFactoryBean.setJobDetail(someJob().getObject());
cronTriggerFactoryBean.setCronExpression(cronExp);
cronTriggerFactoryBean.setGroup(someGroup);
return cronTriggerFactoryBean;
}
@Bean
public JobDetailFactoryBean someJob() {
JobDetailFactoryBean jobDetailFactory = new JobDetailFactoryBean();
jobDetailFactory.setJobClass(SomeJob.class);
jobDetailFactory.setGroup(someGroup);
jobDetailFactory.setDurability(true);
return jobDetailFactory;
}
@Bean
public Properties quartzProperties() {
PropertiesFactoryBean propertiesFactoryBean = new PropertiesFactoryBean();
propertiesFactoryBean.setLocation(new ClassPathResource("/quartz.properties"));
Properties properties = null;
try {
propertiesFactoryBean.afterPropertiesSet();
properties = propertiesFactoryBean.getObject();
} catch (IOException e) {
}
return properties;
}
}
如何让Quartz通过构造函数连接到适当的依赖项中?如中所述:
这种行为的后果之一是,乔布斯必须
具有无参数构造函数(使用默认JobFactory时)
实施)
实际上,您使用的是添加了自动布线功能的默认JobFactory。从我的个人测试中,我发现自动布线不能与构造函数注入一起工作。另外,不要用Spring注释(组件、服务、e.c.t)标记您的作业,因为它没有任何效果
为了解决您的问题,重构您的作业,使其具有默认构造函数和带有字段注入的autowire依赖项(也许setter注入也可以)
我刚刚在这里发布了一个答案,只有普通石英具有自动布线功能。 但是,请注意,您需要有一个无参数构造函数(在您的案例中同时使用无参数和参数构造函数)。Quartz使用类名来实例化实例,所以,带参数的构造函数无法工作 如果您仍在处理相同的问题,请尝试我的方法,您可以自动连接所需的依赖项,而不是通过
super(foo)代码>
还要确保您使用的是spring-3.2.1和quartz-2.1.6。如果未发布,请发布您正在使用的石英版本/spring@RobertI使用quartz-2.2、spring-boot-1.5.7和spring-4.3.4这不起作用,因为我得到一个错误:在调用超类型构造函数之前无法引用foo
我不想触及基类,因为它会影响许多其他类classes@Richard,您可以传入难看的null
,更改父类,或将逻辑移出作业,只需委托给调用fooB的某个字段注入bean即可
@Configuration
public class QuartzConfig {
@Autowired
private DataSource dataSource;
@Autowired
private PlatformTransactionManager transactionManager;
@Autowired
private ApplicationContext applicationContext;
@Bean
public SchedulerFactoryBean quartzScheduler() {
SchedulerFactoryBean quartzScheduler = new SchedulerFactoryBean();
quartzScheduler.setDataSource(dataSource);
quartzScheduler.setTransactionManager(transactionManager);
quartzScheduler.setOverwriteExistingJobs(true);
quartzScheduler.setSchedulerName("quartz-jobs");
AutowiringSpringBeanJobFactory jobFactory = new AutowiringSpringBeanJobFactory();
jobFactory.setApplicationContext(applicationContext);
quartzScheduler.setJobFactory(jobFactory);
quartzScheduler.setQuartzProperties(quartzProperties());
Trigger[] triggers = {someJobTrigger().getObject();
quartzScheduler.setTriggers(triggers);
return quartzScheduler;
}
@Bean
public CronTriggerFactoryBean someJobTrigger() {
CronTriggerFactoryBean cronTriggerFactoryBean = new CronTriggerFactoryBean();
cronTriggerFactoryBean.setJobDetail(someJob().getObject());
cronTriggerFactoryBean.setCronExpression(cronExp);
cronTriggerFactoryBean.setGroup(someGroup);
return cronTriggerFactoryBean;
}
@Bean
public JobDetailFactoryBean someJob() {
JobDetailFactoryBean jobDetailFactory = new JobDetailFactoryBean();
jobDetailFactory.setJobClass(SomeJob.class);
jobDetailFactory.setGroup(someGroup);
jobDetailFactory.setDurability(true);
return jobDetailFactory;
}
@Bean
public Properties quartzProperties() {
PropertiesFactoryBean propertiesFactoryBean = new PropertiesFactoryBean();
propertiesFactoryBean.setLocation(new ClassPathResource("/quartz.properties"));
Properties properties = null;
try {
propertiesFactoryBean.afterPropertiesSet();
properties = propertiesFactoryBean.getObject();
} catch (IOException e) {
}
return properties;
}
}
abstract public class AbstractFoo {
@Autowired
protected FooB fooB;
}
public class SomeJob extends AbstractFoo implements Job {
@Override
public void execute(final JobExecutionContext context) throws JobExecutionException {
//do stuff
}
}