以前我把它设置为在石英作业中自动连线。
注意这里。
但是,作业内部类的自动连线将失败。
我的作业代码示例在这里。
public class MyJob extends QuartzJobBean {
@Autowired
private Hello hello; //<--- this is suceess!
@Override
public void executeInternal(JobExecutionContext context) {
//...
Do do = new Do();
do.doSomething();
//...
}
}
做.java
public class Do {
@Autowired
priavte Do2 do2; // <---- ***this is null !***
//...
}
为什么会这样?
我如何解决它,我应该了解更多哪些概念?
Quartz 作业不在与 spring 相同的上下文中运行,因此自动连线的对象在同一类中变为 null。你必须让石英弹簧意识到。
首先添加冲刺上下文支持
<dependency>
<groupId>org.springframework</groupId>
<artifactId>spring-context-support</artifactId>
<version>${spring.version}</version>
</dependency>
然后创建应用程序上下文感知的应用程序上下文持有者
@Component
public final class ApplicationContextHolder extends SpringBeanJobFactory implements ApplicationContextAware {
private static ApplicationContext context;
private transient AutowireCapableBeanFactory beanFactory;
@Override
public void setApplicationContext(ApplicationContext ctx) throws BeansException {
beanFactory = ctx.getAutowireCapableBeanFactory();
context = ctx;
}
@Override
protected Object createJobInstance(final TriggerFiredBundle bundle) throws Exception {
final Object job = super.createJobInstance(bundle);
beanFactory.autowireBean(job);
return job;
}
public static ApplicationContext getContext() {
return context;
}
}
然后,您可以创建石英调度程序配置类
@Configuration
public class QuartzSchedulerConfiguration {
@Autowired
private ApplicationContext applicationContext;
/**
* Create the job factory bean
* @return Job factory bean
*/
@Bean
public JobFactory jobFactory() {
ApplicationContextHolder jobFactory = new ApplicationContextHolder();
jobFactory.setApplicationContext(applicationContext);
return jobFactory;
}
/**
* Create the Scheduler Factory bean
* @return scheduler factory object
*/
@Bean
public SchedulerFactoryBean schedulerFactory() {
SchedulerFactoryBean factory = new SchedulerFactoryBean();
factory.setAutoStartup(true);
factory.setSchedulerName("My Scheduler");
factory.setOverwriteExistingJobs(true);
factory.setJobFactory(jobFactory());
return factory;
}
}
现在,这会将您的石英调度程序置于与 Spring 相同的上下文中,因此您现在可以创建一个 SchedulerService
类。
@Service
public class SchedulerService {
@Autowired
private SchedulerFactoryBean schedulerFactory;
private Scheduler scheduler;
/**
* Initialize the scheduler service
*/
@PostConstruct
private void init() {
scheduler = schedulerFactory.getScheduler();
}
}
现在,您可以使用使用 scheduler
对象创建计划的方法填充此类,当任务被触发时,扩展 Job 的类将使用 Spring 进行上下文感知,并且自动连线的对象将不再为 null
要解决后续问题,请实现ApplicationContextHolder
组件,然后将其自动连接到SchedulerConfig
类
@Autowire
ApplicationContextHolder holder
@Bean
// injecting SpringLiquibase to ensure liquibase is already initialized and created the quartz tables:
public JobFactory jobFactory(SpringLiquibase springLiquibase) {
AutowiringSpringBeanJobFactory jobFactory = new AutowiringSpringBeanJobFactory();
jobFactory.setApplicationContext(holder);
return jobFactory;
}