diff --git a/org.springframework.context/src/main/java/org/springframework/scheduling/annotation/EnableScheduling.java b/org.springframework.context/src/main/java/org/springframework/scheduling/annotation/EnableScheduling.java index 2c671fa3b75..d6742b365fc 100644 --- a/org.springframework.context/src/main/java/org/springframework/scheduling/annotation/EnableScheduling.java +++ b/org.springframework.context/src/main/java/org/springframework/scheduling/annotation/EnableScheduling.java @@ -21,14 +21,136 @@ import java.lang.annotation.ElementType; import java.lang.annotation.Retention; import java.lang.annotation.RetentionPolicy; import java.lang.annotation.Target; +import java.util.concurrent.Executor; +import org.springframework.context.annotation.Configuration; import org.springframework.context.annotation.Import; +import org.springframework.scheduling.Trigger; +import org.springframework.scheduling.config.ScheduledTaskRegistrar; /** - * Enables Spring's scheduled task execution capability. + * Enables Spring's scheduled task execution capability, similar to + * functionality found in Spring's {@code } XML namespace. To be used + * on @{@link Configuration} classes as follows: + * + *
+ * @Configuration
+ * @EnableScheduling
+ * public class AppConfig {
+ *     // various @Bean definitions
+ * }
+ * + * This enables detection of @{@link Scheduled} annotations on any Spring-managed + * bean in the container. For example, given a class {@code MyTask} + * + *
+ * package com.myco.tasks;
+ *
+ * public class MyTask {
+ *     @Scheduled(fixedRate=1000)
+ *     public void work() {
+ *         // task execution logic
+ *     }
+ * }
+ * + * the following configuration would ensure that {@code MyTask.work()} is called + * once every 1000 ms: + * + *
+ * @Configuration
+ * @EnableScheduling
+ * public class AppConfig {
+ *     @Bean
+ *     public MyTask task() {
+ *         return new MyTask();
+ *     }
+ * }
+ * + * Alternatively, if {@code MyTask} were annotated with {@code @Component}, the + * following configuration would ensure that its {@code @Scheduled} method is + * invoked at the desired interval: + * + *
+ * @Configuration
+ * @ComponentScan(basePackages="com.myco.tasks")
+ * public class AppConfig {
+ * }
+ * + * Methods annotated with {@code @Scheduled} may even be declared directly within + * {@code @Configuration} classes: + * + *
+ * @Configuration
+ * @EnableScheduling
+ * public class AppConfig {
+ *     @Scheduled(fixedRate=1000)
+ *     public void work() {
+ *         // task execution logic
+ *     }
+ * }
+ * + * In all of the above scenarios, a default single-threaded task executor is used. + * When more control is desired, a {@code @Configuration} class may implement + * {@link SchedulingConfigurer}. This allows access to the underlying + * {@link ScheduledTaskRegistrar} instance. For example, the following example + * demonstrates how to customize the {@link Executor} used to execute scheduled + * tasks: + * + *
+ * @Configuration
+ * @EnableScheduling
+ * public class AppConfig implements SchedulingConfigurer {
+ *     @Override
+ *     public void configureTasks(ScheduledTaskRegistrar taskRegistrar) {
+ *         taskRegistrar.setScheduler(taskExecutor());
+ *     }
+ *
+ *     @Bean
+ *     public Executor taskExecutor() {
+ *         return Executors.newScheduledThreadPool(100);
+ *     }
+ * }
+ * + * Implementing {@code SchedulingConfigurer} also allows for fine-grained + * control over task registration via the {@code ScheduledTaskRegistrar}. + * For example, the following configures the execution of a particular bean + * method per a custom {@code Trigger} implementation: + * + *
+ * @Configuration
+ * @EnableScheduling
+ * public class AppConfig implements SchedulingConfigurer {
+ *     @Override
+ *     public void configureTasks(ScheduledTaskRegistrar taskRegistrar) {
+ *         taskRegistrar.setScheduler(taskExecutor());
+ *         taskRegistrar.addTriggerTask(
+ *         addTriggerTask(
+ *             new Runnable() {
+ *                 task().work();
+ *             },
+ *             new CustomTrigger()
+ *         );
+ *     }
+ *
+ *     @Bean
+ *     public Executor taskExecutor() {
+ *         return Executors.newScheduledThreadPool(100);
+ *     }
+ *
+ *     @Bean
+ *     public MyTask task() {
+ *         return new MyTask();
+ *     }
+ * }
* * @author Chris Beams * @since 3.1 + * @see Scheduled + * @see SchedulingConfiguration + * @see SchedulingConfigurer + * @see ScheduledTaskRegistrar + * @see Trigger + * @see ScheduledAnnotationBeanPostProcessor */ @Target(ElementType.TYPE) @Retention(RetentionPolicy.RUNTIME) diff --git a/org.springframework.context/src/main/java/org/springframework/scheduling/annotation/ScheduledAnnotationBeanPostProcessor.java b/org.springframework.context/src/main/java/org/springframework/scheduling/annotation/ScheduledAnnotationBeanPostProcessor.java index da57390d986..ec06fc0fe4d 100644 --- a/org.springframework.context/src/main/java/org/springframework/scheduling/annotation/ScheduledAnnotationBeanPostProcessor.java +++ b/org.springframework.context/src/main/java/org/springframework/scheduling/annotation/ScheduledAnnotationBeanPostProcessor.java @@ -32,6 +32,7 @@ import org.springframework.context.event.ContextRefreshedEvent; import org.springframework.core.Ordered; import org.springframework.core.annotation.AnnotationUtils; import org.springframework.scheduling.TaskScheduler; +import org.springframework.scheduling.Trigger; import org.springframework.scheduling.config.ScheduledTaskRegistrar; import org.springframework.scheduling.support.ScheduledMethodRunnable; import org.springframework.util.Assert; @@ -40,15 +41,25 @@ import org.springframework.util.ReflectionUtils.MethodCallback; import org.springframework.util.StringValueResolver; /** - * Bean post-processor that registers methods annotated with {@link Scheduled @Scheduled} + * Bean post-processor that registers methods annotated with @{@link Scheduled} * to be invoked by a {@link org.springframework.scheduling.TaskScheduler} according * to the "fixedRate", "fixedDelay", or "cron" expression provided via the annotation. * + *

This post-processor is automatically registered by Spring's + * {@code } XML element, and also by the @{@link EnableScheduling} + * annotation. + * + *

Auto-detects any {@link SchedulingConfigurer} instances in the container, + * allowing for customization of the scheduler to be used or for fine-grained control + * over task registration (e.g. registration of {@link Trigger} tasks. + * See @{@link EnableScheduling} Javadoc for complete usage details. + * * @author Mark Fisher * @author Juergen Hoeller * @author Chris Beams * @since 3.0 * @see Scheduled + * @see EnableScheduling * @see SchedulingConfigurer * @see org.springframework.scheduling.TaskScheduler * @see org.springframework.scheduling.config.ScheduledTaskRegistrar diff --git a/org.springframework.context/src/main/java/org/springframework/scheduling/annotation/SchedulingConfiguration.java b/org.springframework.context/src/main/java/org/springframework/scheduling/annotation/SchedulingConfiguration.java index ab08f1e2de8..2808d8599e7 100644 --- a/org.springframework.context/src/main/java/org/springframework/scheduling/annotation/SchedulingConfiguration.java +++ b/org.springframework.context/src/main/java/org/springframework/scheduling/annotation/SchedulingConfiguration.java @@ -22,6 +22,19 @@ import org.springframework.context.annotation.Bean; import org.springframework.context.annotation.Configuration; import org.springframework.context.annotation.Role; +/** + * Configures a {@link ScheduledAnnotationBeanPostProcessor} bean capable of + * processing Spring's @{@link Scheduled} annotation. + * + *

This {@code @Configuration} class is automatically imported when using + * the @{@link EnableScheduling} annotation. See {@code @EnableScheduling} + * Javadoc for complete usage details. + * + * @author Chris Beams + * @since 3.1 + * @see EnableScheduling + * @see ScheduledAnnotationBeanPostProcessor + */ @Configuration public class SchedulingConfiguration {