Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Quartz does not support @autowired

I am implement a Quartz job using a DAO service as below:

public class InitialFetchFrequenceScheduleJob implements Job
{
    @Autowired
    private FetchFrequencyService fetchFrequencyService;

    @Override
    public void execute(JobExecutionContext context) throws JobExecutionException
    {
        try
        {
            List<FetchFrequency> frequencies = this.fetchFrequencyService.findAll(FetchFrequency.class);

The problem is, when call execute() method, the this.fetchFrequencyService.findAll(FetchFrequency.class); will throw NPE because fetchFrequenceService is null. I do anything wrong here? Any reply is much appreciated. Thank you!

P/s I am using Quartz 2.1.7

Update: This is FetchFrequencyServiceImpl:

@Service("fetchFrequencyService")
public class FetchFrequencyServiceImpl extends GenericDaoImpl implements FetchFrequencyService
{
}

Update: The code implement job:

JobDetail job = JobBuilder.newJob(InitialFetchFrequenceScheduleJob.class).build();
        Calendar cal = Calendar.getInstance();
        cal.add(Calendar.MINUTE, 1);
        Trigger trigger = TriggerBuilder.newTrigger().forJob(job).startAt(cal.getTime()).build();
        Scheduler scheduler = new StdSchedulerFactory("quartz.properties").getScheduler();
        scheduler.start();
        scheduler.scheduleJob(job, trigger);
like image 831
jack Avatar asked Sep 08 '14 07:09

jack


2 Answers

@Autowired will not work in a Quartz job implementation because it will not be instantiated by Spring. In order to get hold of Spring-managed beans in a Quartz job you should first of all use org.springframework.scheduling.quartz.SchedulerFactoryBean to manage the Quartz lifecycle. Using this FactoryBean you can specify the applicationContextSchedulerContextKey property to have a reference to the ApplicationContext supplied to your Quartz job in the scheduler context, e.g.:

<bean id="scheduler"
    class="org.springframework.scheduling.quartz.SchedulerFactoryBean">
    <property name="applicationContextSchedulerContextKey" value="applicationContext" />
    <!-- additional properties here -->
</bean>

You can now retrieve the ApplicationContext reference in your job, and then explicitly get the bean reference from the ApplicationContext:

@Override
public void execute(JobExecutionContext context) throws JobExecutionException {
    ApplicationContext applicationContext = (ApplicationContext) executionContext
               .getScheduler().getContext().get("applicationContext");

    FetchFrequencyService service = applicationContext.getBean(FetchFrequencyService.class);

    // Start using your service.
}
like image 98
marthursson Avatar answered Nov 15 '22 09:11

marthursson


The way you are using Quartz does not get Spring involved in the process at all, and therefor no wiring of dependencies takes place.

I suggest you take a look at this part of the official documentation for the basic info on how to integrate Spring with Quartz as well as this great SO answer

like image 41
geoand Avatar answered Nov 15 '22 08:11

geoand