@Target(value=TYPE) @Retention(value=RUNTIME) @Import(value=SchedulingConfiguration.class) @Documented public @interface EnableScheduling
<task:*>
XML namespace. To be used
on @Configuration
classes as follows:
@Configuration @EnableScheduling public class AppConfig { // various @Bean definitions }
This enables detection of @Scheduled
annotations on any
Spring-managed bean in the container. For example, given a class MyTask
:
package com.myco.tasks; public class MyTask { @Scheduled(fixedRate=1000) public void work() { // task execution logic } }
the following configuration would ensure that MyTask.work()
is called
once every 1000 ms:
@Configuration @EnableScheduling public class AppConfig { @Bean public MyTask task() { return new MyTask(); } }
Alternatively, if MyTask
were annotated with @Component
, the
following configuration would ensure that its @Scheduled
method is
invoked at the desired interval:
@Configuration @EnableScheduling @ComponentScan(basePackages="com.myco.tasks") public class AppConfig { }
Methods annotated with @Scheduled
may even be declared directly within
@Configuration
classes:
@Configuration @EnableScheduling public class AppConfig { @Scheduled(fixedRate=1000) public void work() { // task execution logic } }
By default, Spring will search for an associated scheduler definition: either
a unique TaskScheduler
bean in the context,
or a TaskScheduler
bean named "taskScheduler" otherwise; the same lookup
will also be performed for a ScheduledExecutorService
bean. If neither of the two is resolvable, a local single-threaded default
scheduler will be created and used within the registrar.
When more control is desired, a @Configuration
class may implement
SchedulingConfigurer
. This allows access to the underlying
ScheduledTaskRegistrar
instance. For example, the following example
demonstrates how to customize the Executor
used to execute scheduled
tasks:
@Configuration @EnableScheduling public class AppConfig implements SchedulingConfigurer { @Override public void configureTasks(ScheduledTaskRegistrar taskRegistrar) { taskRegistrar.setScheduler(taskExecutor()); } @Bean(destroyMethod="shutdown") public Executor taskExecutor() { return Executors.newScheduledThreadPool(100); } }
Note in the example above the use of @Bean(destroyMethod="shutdown")
.
This ensures that the task executor is properly shut down when the Spring
application context itself is closed.
Implementing SchedulingConfigurer
also allows for fine-grained
control over task registration via the ScheduledTaskRegistrar
.
For example, the following configures the execution of a particular bean
method per a custom Trigger
implementation:
@Configuration @EnableScheduling public class AppConfig implements SchedulingConfigurer { @Override public void configureTasks(ScheduledTaskRegistrar taskRegistrar) { taskRegistrar.setScheduler(taskScheduler()); taskRegistrar.addTriggerTask( () -> myTask().work(), new CustomTrigger() ); } @Bean(destroyMethod="shutdown") public Executor taskScheduler() { return Executors.newScheduledThreadPool(42); } @Bean public MyTask myTask() { return new MyTask(); } }
For reference, the example above can be compared to the following Spring XML configuration:
<beans> <task:annotation-driven scheduler="taskScheduler"/> <task:scheduler id="taskScheduler" pool-size="42"/> <task:scheduled-tasks scheduler="taskScheduler"> <task:scheduled ref="myTask" method="work" fixed-rate="1000"/> </task:scheduled-tasks> <bean id="myTask" class="com.foo.MyTask"/> </beans>
The examples are equivalent save that in XML a fixed-rate period is used
instead of a custom Trigger
implementation; this is because the
task:
namespace scheduled
cannot easily expose such support. This is
but one demonstration how the code-based approach allows for maximum configurability
through direct access to actual componentry.
Note: @EnableScheduling
applies to its local application context only,
allowing for selective scheduling of beans at different levels. Please redeclare
@EnableScheduling
in each individual context, e.g. the common root web
application context and any separate DispatcherServlet
application contexts,
if you need to apply its behavior at multiple levels.
Scheduled
,
SchedulingConfiguration
,
SchedulingConfigurer
,
ScheduledTaskRegistrar
,
Trigger
,
ScheduledAnnotationBeanPostProcessor