001/* 002 * Copyright 2002-2016 the original author or authors. 003 * 004 * Licensed under the Apache License, Version 2.0 (the "License"); 005 * you may not use this file except in compliance with the License. 006 * You may obtain a copy of the License at 007 * 008 * https://www.apache.org/licenses/LICENSE-2.0 009 * 010 * Unless required by applicable law or agreed to in writing, software 011 * distributed under the License is distributed on an "AS IS" BASIS, 012 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 013 * See the License for the specific language governing permissions and 014 * limitations under the License. 015 */ 016 017package org.springframework.scheduling.annotation; 018 019import java.lang.annotation.Documented; 020import java.lang.annotation.ElementType; 021import java.lang.annotation.Retention; 022import java.lang.annotation.RetentionPolicy; 023import java.lang.annotation.Target; 024import java.util.concurrent.Executor; 025 026import org.springframework.context.annotation.Configuration; 027import org.springframework.context.annotation.Import; 028import org.springframework.scheduling.Trigger; 029import org.springframework.scheduling.config.ScheduledTaskRegistrar; 030 031/** 032 * Enables Spring's scheduled task execution capability, similar to 033 * functionality found in Spring's {@code <task:*>} XML namespace. To be used 034 * on @{@link Configuration} classes as follows: 035 * 036 * <pre class="code"> 037 * @Configuration 038 * @EnableScheduling 039 * public class AppConfig { 040 * 041 * // various @Bean definitions 042 * }</pre> 043 * 044 * This enables detection of @{@link Scheduled} annotations on any Spring-managed 045 * bean in the container. For example, given a class {@code MyTask} 046 * 047 * <pre class="code"> 048 * package com.myco.tasks; 049 * 050 * public class MyTask { 051 * 052 * @Scheduled(fixedRate=1000) 053 * public void work() { 054 * // task execution logic 055 * } 056 * }</pre> 057 * 058 * the following configuration would ensure that {@code MyTask.work()} is called 059 * once every 1000 ms: 060 * 061 * <pre class="code"> 062 * @Configuration 063 * @EnableScheduling 064 * public class AppConfig { 065 * 066 * @Bean 067 * public MyTask task() { 068 * return new MyTask(); 069 * } 070 * }</pre> 071 * 072 * Alternatively, if {@code MyTask} were annotated with {@code @Component}, the 073 * following configuration would ensure that its {@code @Scheduled} method is 074 * invoked at the desired interval: 075 * 076 * <pre class="code"> 077 * @Configuration 078 * @EnableScheduling 079 * @ComponentScan(basePackages="com.myco.tasks") 080 * public class AppConfig { 081 * }</pre> 082 * 083 * Methods annotated with {@code @Scheduled} may even be declared directly within 084 * {@code @Configuration} classes: 085 * 086 * <pre class="code"> 087 * @Configuration 088 * @EnableScheduling 089 * public class AppConfig { 090 * 091 * @Scheduled(fixedRate=1000) 092 * public void work() { 093 * // task execution logic 094 * } 095 * }</pre> 096 * 097 * <p>By default, will be searching for an associated scheduler definition: either 098 * a unique {@link org.springframework.scheduling.TaskScheduler} bean in the context, 099 * or a {@code TaskScheduler} bean named "taskScheduler" otherwise; the same lookup 100 * will also be performed for a {@link java.util.concurrent.ScheduledExecutorService} 101 * bean. If neither of the two is resolvable, a local single-threaded default 102 * scheduler will be created and used within the registrar. 103 * 104 * <p>When more control is desired, a {@code @Configuration} class may implement 105 * {@link SchedulingConfigurer}. This allows access to the underlying 106 * {@link ScheduledTaskRegistrar} instance. For example, the following example 107 * demonstrates how to customize the {@link Executor} used to execute scheduled 108 * tasks: 109 * 110 * <pre class="code"> 111 * @Configuration 112 * @EnableScheduling 113 * public class AppConfig implements SchedulingConfigurer { 114 * 115 * @Override 116 * public void configureTasks(ScheduledTaskRegistrar taskRegistrar) { 117 * taskRegistrar.setScheduler(taskExecutor()); 118 * } 119 * 120 * @Bean(destroyMethod="shutdown") 121 * public Executor taskExecutor() { 122 * return Executors.newScheduledThreadPool(100); 123 * } 124 * }</pre> 125 * 126 * <p>Note in the example above the use of {@code @Bean(destroyMethod="shutdown")}. 127 * This ensures that the task executor is properly shut down when the Spring 128 * application context itself is closed. 129 * 130 * <p>Implementing {@code SchedulingConfigurer} also allows for fine-grained 131 * control over task registration via the {@code ScheduledTaskRegistrar}. 132 * For example, the following configures the execution of a particular bean 133 * method per a custom {@code Trigger} implementation: 134 * 135 * <pre class="code"> 136 * @Configuration 137 * @EnableScheduling 138 * public class AppConfig implements SchedulingConfigurer { 139 * 140 * @Override 141 * public void configureTasks(ScheduledTaskRegistrar taskRegistrar) { 142 * taskRegistrar.setScheduler(taskScheduler()); 143 * taskRegistrar.addTriggerTask( 144 * new Runnable() { 145 * public void run() { 146 * myTask().work(); 147 * } 148 * }, 149 * new CustomTrigger() 150 * ); 151 * } 152 * 153 * @Bean(destroyMethod="shutdown") 154 * public Executor taskScheduler() { 155 * return Executors.newScheduledThreadPool(42); 156 * } 157 * 158 * @Bean 159 * public MyTask myTask() { 160 * return new MyTask(); 161 * } 162 * }</pre> 163 * 164 * <p>For reference, the example above can be compared to the following Spring XML 165 * configuration: 166 * 167 * <pre class="code"> 168 * {@code 169 * <beans> 170 * 171 * <task:annotation-driven scheduler="taskScheduler"/> 172 * 173 * <task:scheduler id="taskScheduler" pool-size="42"/> 174 * 175 * <task:scheduled-tasks scheduler="taskScheduler"> 176 * <task:scheduled ref="myTask" method="work" fixed-rate="1000"/> 177 * </task:scheduled-tasks> 178 * 179 * <bean id="myTask" class="com.foo.MyTask"/> 180 * 181 * </beans> 182 * }</pre> 183 * 184 * The examples are equivalent save that in XML a <em>fixed-rate</em> period is used 185 * instead of a custom <em>{@code Trigger}</em> implementation; this is because the 186 * {@code task:} namespace {@code scheduled} cannot easily expose such support. This is 187 * but one demonstration how the code-based approach allows for maximum configurability 188 * through direct access to actual componentry.<p> 189 * 190 * @author Chris Beams 191 * @author Juergen Hoeller 192 * @since 3.1 193 * @see Scheduled 194 * @see SchedulingConfiguration 195 * @see SchedulingConfigurer 196 * @see ScheduledTaskRegistrar 197 * @see Trigger 198 * @see ScheduledAnnotationBeanPostProcessor 199 */ 200@Target(ElementType.TYPE) 201@Retention(RetentionPolicy.RUNTIME) 202@Import(SchedulingConfiguration.class) 203@Documented 204public @interface EnableScheduling { 205 206}