Spring Framework integration support for caching (Caffeine, JCache), mail (JavaMail), scheduling (Quartz), and template engines (FreeMarker)
—
Spring Context Support provides enterprise-grade job scheduling integration with Quartz Scheduler. It supports cron-based triggers, method-invoking jobs, Spring dependency injection for scheduled tasks, and comprehensive lifecycle management.
Primary entry point for Quartz scheduler integration with full Spring lifecycle support and configuration management.
/**
* FactoryBean for creating and configuring a Quartz Scheduler
*/
public class SchedulerFactoryBean implements FactoryBean<Scheduler>, BeanNameAware,
ApplicationContextAware, InitializingBean, DisposableBean, SmartLifecycle {
/**
* Set the SchedulerFactory to use
* @param schedulerFactory the SchedulerFactory instance
*/
public void setSchedulerFactory(SchedulerFactory schedulerFactory);
/**
* Set the SchedulerFactory class to instantiate
* @param schedulerFactoryClass the SchedulerFactory class
*/
public void setSchedulerFactoryClass(Class<? extends SchedulerFactory> schedulerFactoryClass);
/**
* Set the scheduler name
* @param schedulerName the scheduler name
*/
public void setSchedulerName(String schedulerName);
/**
* Set the location of the Quartz properties file
* @param configLocation the properties file location
*/
public void setConfigLocation(Resource configLocation);
/**
* Set Quartz properties directly
* @param quartzProperties the Quartz properties
*/
public void setQuartzProperties(Properties quartzProperties);
/**
* Set the TaskExecutor for background task execution
* @param taskExecutor the TaskExecutor to use
*/
public void setTaskExecutor(Executor taskExecutor);
/**
* Set the DataSource for persistent job storage
* @param dataSource the DataSource to use
*/
public void setDataSource(DataSource dataSource);
/**
* Set the non-transactional DataSource for job storage
* @param nonTransactionalDataSource the non-transactional DataSource
*/
public void setNonTransactionalDataSource(DataSource nonTransactionalDataSource);
/**
* Set scheduler context parameters
* @param schedulerContextMap map of context parameters
*/
public void setSchedulerContextAsMap(Map<String, ?> schedulerContextMap);
/**
* Set the key for storing ApplicationContext in scheduler context
* @param applicationContextSchedulerContextKey the context key
*/
public void setApplicationContextSchedulerContextKey(String applicationContextSchedulerContextKey);
/**
* Set job factory for creating job instances
* @param jobFactory the job factory
*/
public void setJobFactory(JobFactory jobFactory);
/**
* Set whether to auto-start the scheduler after initialization
* @param autoStartup whether to auto-start
*/
public void setAutoStartup(boolean autoStartup);
/**
* Set the startup/shutdown phase
* @param phase the phase value
*/
public void setPhase(int phase);
/**
* Get the startup/shutdown phase
* @return the phase value
*/
public int getPhase();
/**
* Set the startup delay in seconds
* @param startupDelay delay in seconds
*/
public void setStartupDelay(int startupDelay);
/**
* Set whether to expose scheduler in repository
* @param exposeSchedulerInRepository whether to expose in repository
*/
public void setExposeSchedulerInRepository(boolean exposeSchedulerInRepository);
/**
* Set whether to wait for jobs to complete on shutdown
* @param waitForJobsToCompleteOnShutdown whether to wait for jobs
*/
public void setWaitForJobsToCompleteOnShutdown(boolean waitForJobsToCompleteOnShutdown);
/**
* Set triggers to be registered with the scheduler
* @param triggers array of triggers
*/
public void setTriggers(Trigger... triggers);
/**
* Set job details to be registered with the scheduler
* @param jobDetails array of job details
*/
public void setJobDetails(JobDetail... jobDetails);
/**
* Set calendars to be registered with the scheduler
* @param calendars map of calendar names to Calendar objects
*/
public void setCalendars(Map<String, Calendar> calendars);
/**
* Get the Scheduler instance managed by this factory
* @return the Scheduler instance
*/
public Scheduler getScheduler();
/**
* Get the created Scheduler instance
* @return the Scheduler instance
*/
@Override
public Scheduler getObject();
}Usage Examples:
@Configuration
@EnableScheduling
public class QuartzConfig {
@Bean
public SchedulerFactoryBean schedulerFactoryBean() {
SchedulerFactoryBean factory = new SchedulerFactoryBean();
factory.setConfigLocation(new ClassPathResource("quartz.properties"));
factory.setJobFactory(springBeanJobFactory());
factory.setAutoStartup(true);
factory.setStartupDelay(30);
factory.setOverwriteExistingJobs(true);
factory.setWaitForJobsToCompleteOnShutdown(true);
return factory;
}
@Bean
public SpringBeanJobFactory springBeanJobFactory() {
SpringBeanJobFactory jobFactory = new SpringBeanJobFactory();
jobFactory.setApplicationContext(applicationContext);
return jobFactory;
}
// Complete scheduler configuration with jobs and triggers
@Bean
public SchedulerFactoryBean completeScheduler() {
SchedulerFactoryBean factory = new SchedulerFactoryBean();
// Set jobs and triggers
factory.setJobDetails(
emailReportJobDetail().getObject(),
dataCleanupJobDetail().getObject()
);
factory.setTriggers(
emailReportTrigger().getObject(),
dataCleanupTrigger().getObject()
);
return factory;
}
}Factory beans for creating and configuring Quartz job details with Spring integration.
/**
* FactoryBean for creating Quartz JobDetail objects
*/
public class JobDetailFactoryBean implements FactoryBean<JobDetail>, BeanNameAware, InitializingBean {
/**
* Set the job class to execute
* @param jobClass the job class
*/
public void setJobClass(Class<? extends Job> jobClass);
/**
* Set the job name
* @param name the job name
*/
public void setName(String name);
/**
* Set the job group
* @param group the job group
*/
public void setGroup(String group);
/**
* Set job description
* @param description the job description
*/
public void setDescription(String description);
/**
* Set job data as a Map
* @param jobDataAsMap map of job data
*/
public void setJobDataAsMap(Map<String, ?> jobDataAsMap);
/**
* Set job durability (whether job persists without triggers)
* @param durability whether the job should be durable
*/
public void setDurability(boolean durability);
/**
* Set whether the job should request recovery after scheduler failure
* @param requestsRecovery whether to request recovery
*/
public void setRequestsRecovery(boolean requestsRecovery);
/**
* Get the created JobDetail
* @return the JobDetail instance
*/
@Override
public JobDetail getObject();
}
/**
* FactoryBean for method-invoking job details
*/
public class MethodInvokingJobDetailFactoryBean extends JobDetailFactoryBean
implements BeanClassLoaderAware, BeanFactoryAware, BeanNameAware, InitializingBean {
/**
* Set the target object to invoke methods on
* @param targetObject the target object
*/
public void setTargetObject(Object targetObject);
/**
* Set the target class for static method invocation
* @param targetClass the target class
*/
public void setTargetClass(Class<?> targetClass);
/**
* Set the target bean name from the application context
* @param targetBeanName the target bean name
*/
public void setTargetBeanName(String targetBeanName);
/**
* Set the method name to invoke
* @param targetMethod the method name
*/
public void setTargetMethod(String targetMethod);
/**
* Set arguments for the method invocation
* @param arguments the method arguments
*/
public void setArguments(Object... arguments);
/**
* Set whether the job is concurrent (default: false)
* @param concurrent whether to allow concurrent execution
*/
public void setConcurrent(boolean concurrent);
}Factory beans for creating different types of Quartz triggers.
/**
* FactoryBean for creating cron-based triggers
*/
public class CronTriggerFactoryBean implements FactoryBean<CronTrigger>, BeanNameAware, InitializingBean {
/**
* Set the cron expression
* @param cronExpression the cron expression
*/
public void setCronExpression(String cronExpression);
/**
* Set the time zone for the cron expression
* @param timeZone the time zone
*/
public void setTimeZone(TimeZone timeZone);
/**
* Set the JobDetail this trigger should fire
* @param jobDetail the job detail
*/
public void setJobDetail(JobDetail jobDetail);
/**
* Set the trigger name
* @param name the trigger name
*/
public void setName(String name);
/**
* Set the trigger group
* @param group the trigger group
*/
public void setGroup(String group);
/**
* Set the trigger description
* @param description the trigger description
*/
public void setDescription(String description);
/**
* Set the start time
* @param startTime the start time
*/
public void setStartTime(Date startTime);
/**
* Set the start delay in milliseconds
* @param startDelay delay in milliseconds
*/
public void setStartDelay(long startDelay);
/**
* Set trigger priority
* @param priority the priority (default: 5)
*/
public void setPriority(int priority);
/**
* Set misfire instruction
* @param misfireInstruction the misfire instruction
*/
public void setMisfireInstruction(int misfireInstruction);
/**
* Set job data map
* @param jobDataMap the job data map
*/
public void setJobDataMap(JobDataMap jobDataMap);
/**
* Get the created CronTrigger
* @return the CronTrigger instance
*/
@Override
public CronTrigger getObject();
}
/**
* FactoryBean for creating simple triggers
*/
public class SimpleTriggerFactoryBean implements FactoryBean<SimpleTrigger>, BeanNameAware, InitializingBean {
/**
* Set the JobDetail this trigger should fire
* @param jobDetail the job detail
*/
public void setJobDetail(JobDetail jobDetail);
/**
* Set the start time
* @param startTime the start time
*/
public void setStartTime(Date startTime);
/**
* Set the start delay in milliseconds
* @param startDelay delay in milliseconds
*/
public void setStartDelay(long startDelay);
/**
* Set the repeat interval in milliseconds
* @param repeatInterval interval in milliseconds
*/
public void setRepeatInterval(long repeatInterval);
/**
* Set the repeat count (-1 for infinite)
* @param repeatCount the repeat count
*/
public void setRepeatCount(int repeatCount);
/**
* Set misfire instruction
* @param misfireInstruction the misfire instruction
*/
public void setMisfireInstruction(int misfireInstruction);
/**
* Get the created SimpleTrigger
* @return the SimpleTrigger instance
*/
@Override
public SimpleTrigger getObject();
}Usage Examples:
@Configuration
public class JobConfig {
@Bean
public JobDetailFactoryBean emailReportJobDetail() {
JobDetailFactoryBean factory = new JobDetailFactoryBean();
factory.setJobClass(EmailReportJob.class);
factory.setName("emailReportJob");
factory.setGroup("reports");
factory.setDescription("Daily email report job");
factory.setDurability(true);
Map<String, Object> jobData = new HashMap<>();
jobData.put("reportType", "daily");
jobData.put("recipients", Arrays.asList("admin@example.com"));
factory.setJobDataAsMap(jobData);
return factory;
}
@Bean
public CronTriggerFactoryBean emailReportTrigger() {
CronTriggerFactoryBean factory = new CronTriggerFactoryBean();
factory.setJobDetail(emailReportJobDetail().getObject());
factory.setCronExpression("0 0 8 * * ?"); // Daily at 8 AM
factory.setName("emailReportTrigger");
factory.setGroup("reports");
return factory;
}
@Bean
public MethodInvokingJobDetailFactoryBean methodInvokingJob() {
MethodInvokingJobDetailFactoryBean factory = new MethodInvokingJobDetailFactoryBean();
factory.setTargetBeanName("dataService");
factory.setTargetMethod("cleanupExpiredData");
factory.setName("dataCleanupJob");
factory.setConcurrent(false);
return factory;
}
}Base classes and factories for implementing Spring-aware Quartz jobs.
/**
* Base class for Spring-aware Quartz jobs with automatic property injection
*/
public abstract class QuartzJobBean implements Job {
/**
* Execute the job. Subclasses should implement this method.
* @param context the job execution context
* @throws JobExecutionException if job execution fails
*/
protected abstract void executeInternal(JobExecutionContext context) throws JobExecutionException;
/**
* Set a property value from the JobDataMap
* @param name the property name
* @param value the property value
*/
public final void setBeanName(String name);
/**
* Template method that delegates to executeInternal
* @param context the job execution context
* @throws JobExecutionException if job execution fails
*/
@Override
public final void execute(JobExecutionContext context) throws JobExecutionException;
}
/**
* JobFactory that enables dependency injection for Quartz jobs
*/
public class SpringBeanJobFactory extends AdaptableJobFactory
implements ApplicationContextAware, SchedulerContextAware {
@Override
protected Object createJobInstance(TriggerFiredBundle bundle) throws Exception;
/**
* Set the ApplicationContext for dependency injection
* @param applicationContext the application context
*/
@Override
public void setApplicationContext(ApplicationContext applicationContext);
/**
* Set the SchedulerContext
* @param schedulerContext the scheduler context
*/
@Override
public void setSchedulerContext(SchedulerContext schedulerContext);
}
/**
* Base class for adaptable job factories
*/
public class AdaptableJobFactory implements JobFactory {
/**
* Create a job instance for the given bundle
* @param bundle the trigger fired bundle
* @return the job instance
* @throws Exception if job creation fails
*/
protected Object createJobInstance(TriggerFiredBundle bundle) throws Exception;
/**
* Create a new job instance
* @param bundle the trigger fired bundle
* @return the job instance
* @throws SchedulerException if job creation fails
*/
@Override
public Job newJob(TriggerFiredBundle bundle, Scheduler scheduler) throws SchedulerException;
}
/**
* Job that delegates execution to a target object and method
*/
public class DelegatingJob implements Job {
/**
* Execute the delegated job
* @param context the job execution context
* @throws JobExecutionException if execution fails
*/
@Override
public void execute(JobExecutionContext context) throws JobExecutionException;
}Usage Examples:
@Component
public class EmailReportJob extends QuartzJobBean {
@Autowired
private EmailService emailService;
@Autowired
private ReportService reportService;
// Properties automatically injected from JobDataMap
private String reportType;
private List<String> recipients;
@Override
protected void executeInternal(JobExecutionContext context) throws JobExecutionException {
try {
String report = reportService.generateReport(reportType);
for (String recipient : recipients) {
emailService.sendReport(recipient, "Daily Report", report);
}
log.info("Email report job completed successfully");
} catch (Exception e) {
throw new JobExecutionException("Failed to execute email report job", e);
}
}
// Setters for JobDataMap injection
public void setReportType(String reportType) {
this.reportType = reportType;
}
public void setRecipients(List<String> recipients) {
this.recipients = recipients;
}
}Classes for enhanced Spring integration and custom behavior.
/**
* Interface for beans that need access to the SchedulerContext
*/
public interface SchedulerContextAware {
/**
* Set the SchedulerContext that this object runs in
* @param schedulerContext the SchedulerContext
*/
void setSchedulerContext(SchedulerContext schedulerContext);
}
/**
* JobStore implementation that uses a local DataSource
*/
public class LocalDataSourceJobStore extends JobStoreTX {
/**
* Set the DataSource to use for the JobStore
* @param dataSource the DataSource
*/
public void setDataSource(DataSource dataSource);
/**
* Get the DataSource used by this JobStore
* @return the DataSource
*/
public DataSource getDataSource();
}
/**
* ThreadPool implementation that delegates to a Spring TaskExecutor
*/
public class LocalTaskExecutorThreadPool implements ThreadPool {
/**
* Set the TaskExecutor to delegate to
* @param taskExecutor the TaskExecutor
*/
public void setTaskExecutor(TaskExecutor taskExecutor);
/**
* Get the TaskExecutor being used
* @return the TaskExecutor
*/
public TaskExecutor getTaskExecutor();
@Override
public boolean runInThread(Runnable runnable);
@Override
public int blockForAvailableThreads();
@Override
public void initialize() throws SchedulerConfigException;
@Override
public void shutdown(boolean waitForJobsToComplete);
@Override
public int getPoolSize();
}
/**
* TaskExecutor implementation that uses Quartz SimpleThreadPool
*/
public class SimpleThreadPoolTaskExecutor extends CustomizableThreadFactory
implements TaskExecutor, InitializingBean, DisposableBean {
/**
* Set the thread count
* @param threadCount the number of threads
*/
public void setThreadCount(int threadCount);
/**
* Set the thread priority
* @param threadPriority the thread priority
*/
public void setThreadPriority(int threadPriority);
/**
* Set whether threads should be daemon threads
* @param daemon whether threads are daemon threads
*/
public void setDaemon(boolean daemon);
/**
* Execute a task
* @param task the task to execute
*/
@Override
public void execute(Runnable task);
}Specific exceptions for job scheduling failures.
/**
* Exception thrown when job method invocation fails
*/
public class JobMethodInvocationFailedException extends JobExecutionException {
/**
* Create exception for method invocation failure
* @param methodInvocation the failed method invocation
* @param cause the underlying cause
*/
public JobMethodInvocationFailedException(MethodInvocation methodInvocation, Throwable cause);
/**
* Get details about the failed method invocation
* @return the method invocation details
*/
public MethodInvocation getMethodInvocation();
}Install with Tessl CLI
npx tessl i tessl/maven-org-springframework--spring-context-support