jack
jack

Reputation: 73

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

Upvotes: 5

Views: 11888

Answers (4)

M2E67
M2E67

Reputation: 970

use :

SpringBeanAutowiringSupport.processInjectBasedOnCurrentContext(this)

to autowire your beans in your quartz job

Upvotes: 1

geoand
geoand

Reputation: 64059

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

Upvotes: 1

pappu_kutty
pappu_kutty

Reputation: 2488

you have to annotate your classes with either of following annotation

for DAO

@Repository

service

@Service

controlloer

@Controller

so your service class should have below annotation.

@Service("fetchFrequencyService")
public Class FetchFrequencyService {
}

i thing you need to inject application context into SchedulerFactoryBean

<bean id="scheduler"
        class="org.springframework.scheduling.quartz.SchedulerFactoryBean"
        lazy-init="false">
        <property name="jobFactory">
            <bean class="org.springframework.scheduling.quartz.SpringBeanJobFactory" />
        </property>
        <property name="applicationContextSchedulerContextKey">
            <value>applicationContext</value>
        </property>
</bean>

Upvotes: -1

marthursson
marthursson

Reputation: 3300

@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.
}

Upvotes: 7

Related Questions