How to wire a Quartz Scheduler into my Spring cont

2020-07-06 02:38发布

问题:

I have an application in which I want to use a Quartz Scheduler object. I've read the Spring documentation regarding this and they suggest to use a SchedulerFactoryBean like this:

<bean id="schedulerFactoryBean" class="org.springframework.scheduling.quartz.SchedulerFactoryBean">
    <property name="autoStartup">
        <value>true</value>
    </property>
    <property name="configLocation" value="classpath:quartz.properties" />
</bean>

The config looks like this:

org.quartz.scheduler.skipUpdateCheck = true
org.quartz.scheduler.instanceName = MyQuartzScheduler
org.quartz.scheduler.jobFactory.class = org.quartz.simpl.SimpleJobFactory
org.quartz.threadPool.class = org.quartz.simpl.SimpleThreadPool
org.quartz.threadPool.threadCount = 5
log4j.rootLogger=INFO, stdout
log4j.logger.org.quartz=DEBUG
log4j.appender.stdout=org.apache.log4j.ConsoleAppender
log4j.appender.stdout.layout=org.apache.log4j.PatternLayout
log4j.appender.stdout.layout.ConversionPattern=%5p [%t] (%F:%L) - %m%n

Now if i want to inject schedulerFactoryBean into one of my objects I get an exception stating:

Could not convert constructor argument value of type [org.quartz.impl.StdScheduler] to required type [org.springframework.scheduling.quartz.SchedulerFactoryBean]:

Why do I get a StdScheduler instead of a schedulerFactoryBean? Do I miss a configuration step?

回答1:

A SchedulerFactoryBean is a FactoryBean so it can't be used like a normal bean. When you inject it into other beans, Spring will inject the org.quartz.Scheduler object that the factory produces, it won't inject the factory itself.

It is common to name the factory bean after the object that it produces, as it reads better when you're referencing it. For example:

<bean id="scheduler" class="org.springframework.scheduling.quartz.SchedulerFactoryBean">
    <property name="autoStartup">
        <value>true</value>
    </property>
    <property name="configLocation" value="classpath:quartz.properties" />
</bean>

Then you can configure an object that needs a Scheduler like this:

<bean id="beanThatNeedsScheduler" class="beanThatNeedsScheduler">
    <!-- Will inject a Scheduler not a SchdulerFactoryBean -->
    <property name="scheduler" ref="scheduler" />
</bean>

Or using annotations:

@Component
public class BeanThatNeedsScheduler {

    @Autowired;
    private Scheduler scheduler

    ...
}


回答2:

SchedulerFactoryBean will creates and configures a org.quartz.Quartz,manages its lifecycle as part of the Spring application context, and exposes the Scheduler as bean reference for dependency injection.

<bean class="org.springframework.scheduling.quartz.SchedulerFactoryBean">...</bean>

and you can

@Component
public class YourTask {

@Inject
private Scheduler scheduler

}