mirror of
https://github.com/spring-projects/spring-framework.git
synced 2026-09-29 18:59:03 +00:00
SchedulerFactoryBean always ignores local factory settings in case of an external SchedulerFactory instance (expecting it to be fully initialized)
This commit includes various javadoc fixes and related refinements. Issue: SPR-16439
This commit is contained in:
+5
-4
@@ -1,5 +1,5 @@
|
||||
/*
|
||||
* Copyright 2002-2016 the original author or authors.
|
||||
* Copyright 2002-2018 the original author or authors.
|
||||
*
|
||||
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||
* you may not use this file except in compliance with the License.
|
||||
@@ -25,7 +25,7 @@ import org.quartz.spi.TriggerFiredBundle;
|
||||
import org.springframework.util.ReflectionUtils;
|
||||
|
||||
/**
|
||||
* JobFactory implementation that supports {@link java.lang.Runnable}
|
||||
* {@link JobFactory} implementation that supports {@link java.lang.Runnable}
|
||||
* objects as well as standard Quartz {@link org.quartz.Job} instances.
|
||||
*
|
||||
* <p>Compatible with Quartz 2.1.4 and higher, as of Spring 4.1.
|
||||
@@ -43,7 +43,7 @@ public class AdaptableJobFactory implements JobFactory {
|
||||
Object jobObject = createJobInstance(bundle);
|
||||
return adaptJob(jobObject);
|
||||
}
|
||||
catch (Exception ex) {
|
||||
catch (Throwable ex) {
|
||||
throw new SchedulerException("Job instantiation failed", ex);
|
||||
}
|
||||
}
|
||||
@@ -78,7 +78,8 @@ public class AdaptableJobFactory implements JobFactory {
|
||||
return new DelegatingJob((Runnable) jobObject);
|
||||
}
|
||||
else {
|
||||
throw new IllegalArgumentException("Unable to execute job class [" + jobObject.getClass().getName() +
|
||||
throw new IllegalArgumentException(
|
||||
"Unable to execute job class [" + jobObject.getClass().getName() +
|
||||
"]: only [org.quartz.Job] and [java.lang.Runnable] supported.");
|
||||
}
|
||||
}
|
||||
|
||||
+7
-10
@@ -1,5 +1,5 @@
|
||||
/*
|
||||
* Copyright 2002-2017 the original author or authors.
|
||||
* Copyright 2002-2018 the original author or authors.
|
||||
*
|
||||
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||
* you may not use this file except in compliance with the License.
|
||||
@@ -34,9 +34,9 @@ import org.springframework.jdbc.support.MetaDataAccessException;
|
||||
import org.springframework.lang.Nullable;
|
||||
|
||||
/**
|
||||
* Subclass of Quartz's JobStoreCMT class that delegates to a Spring-managed
|
||||
* DataSource instead of using a Quartz-managed connection pool. This JobStore
|
||||
* will be used if SchedulerFactoryBean's "dataSource" property is set.
|
||||
* Subclass of Quartz's {@link JobStoreCMT} class that delegates to a Spring-managed
|
||||
* {@link DataSource} instead of using a Quartz-managed JDBC connection pool.
|
||||
* This JobStore will be used if SchedulerFactoryBean's "dataSource" property is set.
|
||||
*
|
||||
* <p>Supports both transactional and non-transactional DataSource access.
|
||||
* With a non-XA DataSource and local Spring transactions, a single DataSource
|
||||
@@ -84,15 +84,12 @@ public class LocalDataSourceJobStore extends JobStoreCMT {
|
||||
|
||||
|
||||
@Override
|
||||
public void initialize(ClassLoadHelper loadHelper, SchedulerSignaler signaler)
|
||||
throws SchedulerConfigException {
|
||||
|
||||
public void initialize(ClassLoadHelper loadHelper, SchedulerSignaler signaler) throws SchedulerConfigException {
|
||||
// Absolutely needs thread-bound DataSource to initialize.
|
||||
this.dataSource = SchedulerFactoryBean.getConfigTimeDataSource();
|
||||
if (this.dataSource == null) {
|
||||
throw new SchedulerConfigException(
|
||||
"No local DataSource found for configuration - " +
|
||||
"'dataSource' property must be set on SchedulerFactoryBean");
|
||||
throw new SchedulerConfigException("No local DataSource found for configuration - " +
|
||||
"'dataSource' property must be set on SchedulerFactoryBean");
|
||||
}
|
||||
|
||||
// Configure transactional connection settings for Quartz.
|
||||
|
||||
+6
-7
@@ -1,5 +1,5 @@
|
||||
/*
|
||||
* Copyright 2002-2017 the original author or authors.
|
||||
* Copyright 2002-2018 the original author or authors.
|
||||
*
|
||||
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||
* you may not use this file except in compliance with the License.
|
||||
@@ -28,8 +28,8 @@ import org.springframework.lang.Nullable;
|
||||
import org.springframework.util.Assert;
|
||||
|
||||
/**
|
||||
* Quartz ThreadPool adapter that delegates to a Spring-managed
|
||||
* TaskExecutor instance, specified on SchedulerFactoryBean.
|
||||
* Quartz {@link ThreadPool} adapter that delegates to a Spring-managed
|
||||
* {@link Executor} instance, specified on {@link SchedulerFactoryBean}.
|
||||
*
|
||||
* @author Juergen Hoeller
|
||||
* @since 2.0
|
||||
@@ -55,12 +55,11 @@ public class LocalTaskExecutorThreadPool implements ThreadPool {
|
||||
|
||||
@Override
|
||||
public void initialize() throws SchedulerConfigException {
|
||||
// Absolutely needs thread-bound TaskExecutor to initialize.
|
||||
// Absolutely needs thread-bound Executor to initialize.
|
||||
this.taskExecutor = SchedulerFactoryBean.getConfigTimeTaskExecutor();
|
||||
if (this.taskExecutor == null) {
|
||||
throw new SchedulerConfigException(
|
||||
"No local TaskExecutor found for configuration - " +
|
||||
"'taskExecutor' property must be set on SchedulerFactoryBean");
|
||||
throw new SchedulerConfigException("No local Executor found for configuration - " +
|
||||
"'taskExecutor' property must be set on SchedulerFactoryBean");
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
+64
-68
@@ -104,11 +104,10 @@ public class SchedulerFactoryBean extends SchedulerAccessor implements FactoryBe
|
||||
|
||||
|
||||
/**
|
||||
* Return the ResourceLoader for the currently configured Quartz Scheduler,
|
||||
* to be used by ResourceLoaderClassLoadHelper.
|
||||
* <p>This instance will be set before initialization of the corresponding
|
||||
* Scheduler, and reset immediately afterwards. It is thus only available
|
||||
* during configuration.
|
||||
* Return the {@link ResourceLoader} for the currently configured Quartz Scheduler,
|
||||
* to be used by {@link ResourceLoaderClassLoadHelper}.
|
||||
* <p>This instance will be set before initialization of the corresponding Scheduler,
|
||||
* and reset immediately afterwards. It is thus only available during configuration.
|
||||
* @see #setApplicationContext
|
||||
* @see ResourceLoaderClassLoadHelper
|
||||
*/
|
||||
@@ -118,11 +117,11 @@ public class SchedulerFactoryBean extends SchedulerAccessor implements FactoryBe
|
||||
}
|
||||
|
||||
/**
|
||||
* Return the TaskExecutor for the currently configured Quartz Scheduler,
|
||||
* to be used by LocalTaskExecutorThreadPool.
|
||||
* <p>This instance will be set before initialization of the corresponding
|
||||
* Scheduler, and reset immediately afterwards. It is thus only available
|
||||
* during configuration.
|
||||
* Return the {@link Executor} for the currently configured Quartz Scheduler,
|
||||
* to be used by {@link LocalTaskExecutorThreadPool}.
|
||||
* <p>This instance will be set before initialization of the corresponding Scheduler,
|
||||
* and reset immediately afterwards. It is thus only available during configuration.
|
||||
* @since 2.0
|
||||
* @see #setTaskExecutor
|
||||
* @see LocalTaskExecutorThreadPool
|
||||
*/
|
||||
@@ -132,11 +131,11 @@ public class SchedulerFactoryBean extends SchedulerAccessor implements FactoryBe
|
||||
}
|
||||
|
||||
/**
|
||||
* Return the DataSource for the currently configured Quartz Scheduler,
|
||||
* to be used by LocalDataSourceJobStore.
|
||||
* <p>This instance will be set before initialization of the corresponding
|
||||
* Scheduler, and reset immediately afterwards. It is thus only available
|
||||
* during configuration.
|
||||
* Return the {@link DataSource} for the currently configured Quartz Scheduler,
|
||||
* to be used by {@link LocalDataSourceJobStore}.
|
||||
* <p>This instance will be set before initialization of the corresponding Scheduler,
|
||||
* and reset immediately afterwards. It is thus only available during configuration.
|
||||
* @since 1.1
|
||||
* @see #setDataSource
|
||||
* @see LocalDataSourceJobStore
|
||||
*/
|
||||
@@ -146,11 +145,11 @@ public class SchedulerFactoryBean extends SchedulerAccessor implements FactoryBe
|
||||
}
|
||||
|
||||
/**
|
||||
* Return the non-transactional DataSource for the currently configured
|
||||
* Quartz Scheduler, to be used by LocalDataSourceJobStore.
|
||||
* <p>This instance will be set before initialization of the corresponding
|
||||
* Scheduler, and reset immediately afterwards. It is thus only available
|
||||
* during configuration.
|
||||
* Return the non-transactional {@link DataSource} for the currently configured
|
||||
* Quartz Scheduler, to be used by {@link LocalDataSourceJobStore}.
|
||||
* <p>This instance will be set before initialization of the corresponding Scheduler,
|
||||
* and reset immediately afterwards. It is thus only available during configuration.
|
||||
* @since 1.1
|
||||
* @see #setNonTransactionalDataSource
|
||||
* @see LocalDataSourceJobStore
|
||||
*/
|
||||
@@ -160,11 +159,11 @@ public class SchedulerFactoryBean extends SchedulerAccessor implements FactoryBe
|
||||
}
|
||||
|
||||
|
||||
private Class<? extends SchedulerFactory> schedulerFactoryClass = StdSchedulerFactory.class;
|
||||
|
||||
@Nullable
|
||||
private SchedulerFactory schedulerFactory;
|
||||
|
||||
private Class<? extends SchedulerFactory> schedulerFactoryClass = StdSchedulerFactory.class;
|
||||
|
||||
@Nullable
|
||||
private String schedulerName;
|
||||
|
||||
@@ -174,7 +173,6 @@ public class SchedulerFactoryBean extends SchedulerAccessor implements FactoryBe
|
||||
@Nullable
|
||||
private Properties quartzProperties;
|
||||
|
||||
|
||||
@Nullable
|
||||
private Executor taskExecutor;
|
||||
|
||||
@@ -198,7 +196,6 @@ public class SchedulerFactoryBean extends SchedulerAccessor implements FactoryBe
|
||||
|
||||
private boolean jobFactorySet = false;
|
||||
|
||||
|
||||
private boolean autoStartup = true;
|
||||
|
||||
private int startupDelay = 0;
|
||||
@@ -209,35 +206,20 @@ public class SchedulerFactoryBean extends SchedulerAccessor implements FactoryBe
|
||||
|
||||
private boolean waitForJobsToCompleteOnShutdown = false;
|
||||
|
||||
|
||||
@Nullable
|
||||
private Scheduler scheduler;
|
||||
|
||||
|
||||
/**
|
||||
* Set the Quartz {@link SchedulerFactory} implementation to use.
|
||||
* <p>Default is the {@link StdSchedulerFactory} class, reading in the standard
|
||||
* {@code quartz.properties} from {@code quartz.jar}. For applying custom Quartz
|
||||
* properties, specify {@link #setConfigLocation "configLocation"} or
|
||||
* {@link #setQuartzProperties "quartzProperties"} on {@code SchedulerFactoryBean}.
|
||||
* @see org.quartz.impl.StdSchedulerFactory
|
||||
* @see #setConfigLocation
|
||||
* @see #setQuartzProperties
|
||||
*/
|
||||
public void setSchedulerFactoryClass(Class<? extends SchedulerFactory> schedulerFactoryClass) {
|
||||
this.schedulerFactoryClass = schedulerFactoryClass;
|
||||
}
|
||||
|
||||
/**
|
||||
* Set an external Quartz {@link SchedulerFactory} instance to use.
|
||||
* <p>Default is an internal {@link StdSchedulerFactory} instance. If this method is
|
||||
* called, it overrides any class specified through {@link #setSchedulerFactoryClass}.
|
||||
* <p>An externally provided {@code SchedulerFactory} instance may get initialized
|
||||
* from local {@code SchedulerFactoryBean} settings (such as {@link #setConfigLocation}
|
||||
* or {@link #setQuartzProperties}) but only if it extends from {@link StdSchedulerFactory},
|
||||
* inheriting the common {@link StdSchedulerFactory#initialize(Properties)} method.
|
||||
* Otherwise, all such local settings will be ignored here in {@code SchedulerFactoryBean},
|
||||
* expecting the external {@code SchedulerFactory} instance to get initialized on its own.
|
||||
* called, it overrides any class specified through {@link #setSchedulerFactoryClass}
|
||||
* as well as any settings specified through {@link #setConfigLocation},
|
||||
* {@link #setQuartzProperties}, {@link #setTaskExecutor} or {@link #setDataSource}.
|
||||
* <p><b>NOTE:</b> With an externally provided {@code SchedulerFactory} instance,
|
||||
* local settings such as {@link #setConfigLocation} or {@link #setQuartzProperties}
|
||||
* will be ignored here in {@code SchedulerFactoryBean}, expecting the external
|
||||
* {@code SchedulerFactory} instance to get initialized on its own.
|
||||
* @since 4.3.15
|
||||
* @see #setSchedulerFactoryClass
|
||||
*/
|
||||
@@ -245,6 +227,23 @@ public class SchedulerFactoryBean extends SchedulerAccessor implements FactoryBe
|
||||
this.schedulerFactory = schedulerFactory;
|
||||
}
|
||||
|
||||
/**
|
||||
* Set the Quartz {@link SchedulerFactory} implementation to use.
|
||||
* <p>Default is the {@link StdSchedulerFactory} class, reading in the standard
|
||||
* {@code quartz.properties} from {@code quartz.jar}. For applying custom Quartz
|
||||
* properties, specify {@link #setConfigLocation "configLocation"} and/or
|
||||
* {@link #setQuartzProperties "quartzProperties"} etc on this local
|
||||
* {@code SchedulerFactoryBean} instance.
|
||||
* @see org.quartz.impl.StdSchedulerFactory
|
||||
* @see #setConfigLocation
|
||||
* @see #setQuartzProperties
|
||||
* @see #setTaskExecutor
|
||||
* @see #setDataSource
|
||||
*/
|
||||
public void setSchedulerFactoryClass(Class<? extends SchedulerFactory> schedulerFactoryClass) {
|
||||
this.schedulerFactoryClass = schedulerFactoryClass;
|
||||
}
|
||||
|
||||
/**
|
||||
* Set the name of the Scheduler to create via the SchedulerFactory.
|
||||
* <p>If not specified, the bean name will be used as default scheduler name.
|
||||
@@ -277,14 +276,14 @@ public class SchedulerFactoryBean extends SchedulerAccessor implements FactoryBe
|
||||
this.quartzProperties = quartzProperties;
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* Set the Spring TaskExecutor to use as Quartz backend.
|
||||
* Set a Spring-managed {@link Executor} to use as Quartz backend.
|
||||
* Exposed as thread pool through the Quartz SPI.
|
||||
* <p>Can be used to assign a JDK 1.5 ThreadPoolExecutor or a CommonJ
|
||||
* <p>Can be used to assign a local JDK ThreadPoolExecutor or a CommonJ
|
||||
* WorkManager as Quartz backend, to avoid Quartz's manual thread creation.
|
||||
* <p>By default, a Quartz SimpleThreadPool will be used, configured through
|
||||
* the corresponding Quartz properties.
|
||||
* @since 2.0
|
||||
* @see #setQuartzProperties
|
||||
* @see LocalTaskExecutorThreadPool
|
||||
* @see org.springframework.scheduling.concurrent.ThreadPoolTaskExecutor
|
||||
@@ -295,8 +294,8 @@ public class SchedulerFactoryBean extends SchedulerAccessor implements FactoryBe
|
||||
}
|
||||
|
||||
/**
|
||||
* Set the default DataSource to be used by the Scheduler. If set,
|
||||
* this will override corresponding settings in Quartz properties.
|
||||
* Set the default {@link DataSource} to be used by the Scheduler.
|
||||
* If set, this will override corresponding settings in Quartz properties.
|
||||
* <p>Note: If this is set, the Quartz settings should not define
|
||||
* a job store "dataSource" to avoid meaningless double configuration.
|
||||
* <p>A Spring-specific subclass of Quartz' JobStoreCMT will be used.
|
||||
@@ -309,6 +308,7 @@ public class SchedulerFactoryBean extends SchedulerAccessor implements FactoryBe
|
||||
* argument is sufficient. In case of an XA DataSource and global JTA transactions,
|
||||
* SchedulerFactoryBean's "nonTransactionalDataSource" property should be set,
|
||||
* passing in a non-XA DataSource that will not participate in global transactions.
|
||||
* @since 1.1
|
||||
* @see #setNonTransactionalDataSource
|
||||
* @see #setQuartzProperties
|
||||
* @see #setTransactionManager
|
||||
@@ -319,12 +319,13 @@ public class SchedulerFactoryBean extends SchedulerAccessor implements FactoryBe
|
||||
}
|
||||
|
||||
/**
|
||||
* Set the DataSource to be used by the Scheduler <i>for non-transactional access</i>.
|
||||
* Set the {@link DataSource} to be used <i>for non-transactional access</i>.
|
||||
* <p>This is only necessary if the default DataSource is an XA DataSource that will
|
||||
* always participate in transactions: A non-XA version of that DataSource should
|
||||
* be specified as "nonTransactionalDataSource" in such a scenario.
|
||||
* <p>This is not relevant with a local DataSource instance and Spring transactions.
|
||||
* Specifying a single default DataSource as "dataSource" is sufficient there.
|
||||
* @since 1.1
|
||||
* @see #setDataSource
|
||||
* @see LocalDataSourceJobStore
|
||||
*/
|
||||
@@ -347,7 +348,7 @@ public class SchedulerFactoryBean extends SchedulerAccessor implements FactoryBe
|
||||
}
|
||||
|
||||
/**
|
||||
* Set the key of an ApplicationContext reference to expose in the
|
||||
* Set the key of an {@link ApplicationContext} reference to expose in the
|
||||
* SchedulerContext, for example "applicationContext". Default is none.
|
||||
* Only applicable when running in a Spring ApplicationContext.
|
||||
* <p>Note: When using persistent Jobs whose JobDetail will be kept in the
|
||||
@@ -367,7 +368,7 @@ public class SchedulerFactoryBean extends SchedulerAccessor implements FactoryBe
|
||||
}
|
||||
|
||||
/**
|
||||
* Set the Quartz JobFactory to use for this Scheduler.
|
||||
* Set the Quartz {@link JobFactory} to use for this Scheduler.
|
||||
* <p>Default is Spring's {@link AdaptableJobFactory}, which supports
|
||||
* {@link java.lang.Runnable} objects as well as standard Quartz
|
||||
* {@link org.quartz.Job} instances. Note that this default only applies
|
||||
@@ -376,6 +377,7 @@ public class SchedulerFactoryBean extends SchedulerAccessor implements FactoryBe
|
||||
* <p>Specify an instance of Spring's {@link SpringBeanJobFactory} here
|
||||
* (typically as an inner bean definition) to automatically populate a job's
|
||||
* bean properties from the specified job data map and scheduler context.
|
||||
* @since 2.0
|
||||
* @see AdaptableJobFactory
|
||||
* @see SpringBeanJobFactory
|
||||
*/
|
||||
@@ -384,7 +386,6 @@ public class SchedulerFactoryBean extends SchedulerAccessor implements FactoryBe
|
||||
this.jobFactorySet = true;
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* Set whether to automatically start the scheduler after initialization.
|
||||
* <p>Default is "true"; set this to "false" to allow for manual startup.
|
||||
@@ -404,11 +405,12 @@ public class SchedulerFactoryBean extends SchedulerAccessor implements FactoryBe
|
||||
}
|
||||
|
||||
/**
|
||||
* Specify the phase in which this scheduler should be started and
|
||||
* stopped. The startup order proceeds from lowest to highest, and
|
||||
* the shutdown order is the reverse of that. By default this value
|
||||
* is Integer.MAX_VALUE meaning that this scheduler starts as late
|
||||
* as possible and stops as soon as possible.
|
||||
* Specify the phase in which this scheduler should be started and stopped.
|
||||
* The startup order proceeds from lowest to highest, and the shutdown order
|
||||
* is the reverse of that. By default this value is {@code Integer.MAX_VALUE}
|
||||
* meaning that this scheduler starts as late as possible and stops as soon
|
||||
* as possible.
|
||||
* @since 3.0
|
||||
*/
|
||||
public void setPhase(int phase) {
|
||||
this.phase = phase;
|
||||
@@ -456,7 +458,6 @@ public class SchedulerFactoryBean extends SchedulerAccessor implements FactoryBe
|
||||
this.waitForJobsToCompleteOnShutdown = waitForJobsToCompleteOnShutdown;
|
||||
}
|
||||
|
||||
|
||||
@Override
|
||||
public void setBeanName(String name) {
|
||||
if (this.schedulerName == null) {
|
||||
@@ -548,13 +549,7 @@ public class SchedulerFactoryBean extends SchedulerAccessor implements FactoryBe
|
||||
*/
|
||||
private SchedulerFactory prepareSchedulerFactory() throws SchedulerException, IOException {
|
||||
SchedulerFactory schedulerFactory = this.schedulerFactory;
|
||||
if (schedulerFactory != null) {
|
||||
if (schedulerFactory instanceof StdSchedulerFactory) {
|
||||
initSchedulerFactory((StdSchedulerFactory) schedulerFactory);
|
||||
}
|
||||
// Otherwise, assume that externally provided factory has been initialized with appropriate settings...
|
||||
}
|
||||
else {
|
||||
if (schedulerFactory == null) {
|
||||
// Create local SchedulerFactory instance (typically a StdSchedulerFactory)
|
||||
schedulerFactory = BeanUtils.instantiateClass(this.schedulerFactoryClass);
|
||||
if (schedulerFactory instanceof StdSchedulerFactory) {
|
||||
@@ -567,6 +562,7 @@ public class SchedulerFactoryBean extends SchedulerAccessor implements FactoryBe
|
||||
}
|
||||
// Otherwise, no local settings to be applied via StdSchedulerFactory.initialize(Properties)
|
||||
}
|
||||
// Otherwise, assume that externally provided factory has been initialized with appropriate settings
|
||||
return schedulerFactory;
|
||||
}
|
||||
|
||||
|
||||
Reference in New Issue
Block a user