如何在石英中自动接线



以前我把它设置为在石英作业中自动连线。
注意这里。

但是,作业内部类的自动连线将失败。

我的作业代码示例在这里。

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;
}

最新更新