美文网首页
每天一个Spring Boot注解学习——@EnableSche

每天一个Spring Boot注解学习——@EnableSche

作者: Oliver_Le | 来源:发表于2017-04-17 22:25 被阅读5018次

背景
最近开始做个小项目,用到了Spring Boot,在看前辈书写的代码时,发现其中有许多注解是我之前从来没接触过的。于是决定每天抽点时间,学习总结一下这些陌生的注解,让以后的工作更加有效率。


在Spring Boot 的入口类 XXXApplication 中,必然会有@SpringBootApplication,用来标注项目入口,以及完成一些基本的自动自动配置。但是,在这次项目中,XXXApplication 类中除了@SpringBootApplication注解,还用到了另一个注解,也就是下面要学习的@EnableScheduling注解。
分析
在没有开始学习该注解相关的源码之前,可以从其名称先分析一下作用。
Enable,能够、使...可以。
Schedule, 任务计划、日程。ing形式也就是取其动词形式的语义。
那么也就是说这个注解是用来使计划任务功能可以使用的注解
那么,新的问题就来了,对于没有接触过 Spring 中“计划任务”的我而言,计划任务又是什么呢?
下来,就可以带着问题去看看这个注解的定义类了。
问题:

  1. 这个注解的功能是不是如分析的一样,是启动某种功能的注解?
  2. 关于 “计划任务” 的定义是什么?

话不多说,直接上定义类源码:

/*
 * Copyright 2002-2016 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.
 * You may obtain a copy of the License at
 *
 *      http://www.apache.org/licenses/LICENSE-2.0
 *
 * Unless required by applicable law or agreed to in writing, software
 * distributed under the License is distributed on an "AS IS" BASIS,
 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
 * See the License for the specific language governing permissions and
 * limitations under the License.
 */

package org.springframework.scheduling.annotation;

import java.lang.annotation.Documented;
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, similar to
 * functionality found in Spring's {@code <task:*>} XML namespace. To be used
 * on @{@link Configuration} classes as follows:
 *
 * <pre class="code">
 * @Configuration
 * @EnableScheduling
 * public class AppConfig {
 *
 *     // various @Bean definitions
 * }</pre>
 *
 * This enables detection of @{@link Scheduled} annotations on any Spring-managed
 * bean in the container. For example, given a class {@code MyTask}
 *
 * <pre class="code">
 * package com.myco.tasks;
 *
 * public class MyTask {
 *
 *     @Scheduled(fixedRate=1000)
 *     public void work() {
 *         // task execution logic
 *     }
 * }</pre>
 *
 * the following configuration would ensure that {@code MyTask.work()} is called
 * once every 1000 ms:
 *
 * <pre class="code">
 * @Configuration
 * @EnableScheduling
 * public class AppConfig {
 *
 *     @Bean
 *     public MyTask task() {
 *         return new MyTask();
 *     }
 * }</pre>
 *
 * 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:
 *
 * <pre class="code">
 * @Configuration
 * @EnableScheduling
 * @ComponentScan(basePackages="com.myco.tasks")
 * public class AppConfig {
 * }</pre>
 *
 * Methods annotated with {@code @Scheduled} may even be declared directly within
 * {@code @Configuration} classes:
 *
 * <pre class="code">
 * @Configuration
 * @EnableScheduling
 * public class AppConfig {
 *
 *     @Scheduled(fixedRate=1000)
 *     public void work() {
 *         // task execution logic
 *     }
 * }</pre>
 *
 * <p>By default, will be searching for an associated scheduler definition: either
 * a unique {@link org.springframework.scheduling.TaskScheduler} bean in the context,
 * or a {@code TaskScheduler} bean named "taskScheduler" otherwise; the same lookup
 * will also be performed for a {@link java.util.concurrent.ScheduledExecutorService}
 * bean. If neither of the two is resolvable, a local single-threaded default
 * scheduler will be created and used within the registrar.
 *
 * <p>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:
 *
 * <pre class="code">
 * @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);
 *     }
 * }</pre>
 *
 * <p>Note in the example above the use of {@code @Bean(destroyMethod="shutdown")}.
 * This ensures that the task executor is properly shut down when the Spring
 * application context itself is closed.
 *
 * <p>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:
 *
 * <pre class="code">
 * @Configuration
 * @EnableScheduling
 * public class AppConfig implements SchedulingConfigurer {
 *
 *     @Override
 *     public void configureTasks(ScheduledTaskRegistrar taskRegistrar) {
 *         taskRegistrar.setScheduler(taskScheduler());
 *         taskRegistrar.addTriggerTask(
 *             new Runnable() {
 *                 public void run() {
 *                     myTask().work();
 *                 }
 *             },
 *             new CustomTrigger()
 *         );
 *     }
 *
 *     @Bean(destroyMethod="shutdown")
 *     public Executor taskScheduler() {
 *         return Executors.newScheduledThreadPool(42);
 *     }
 *
 *     @Bean
 *     public MyTask myTask() {
 *         return new MyTask();
 *     }
 * }</pre>
 *
 * <p>For reference, the example above can be compared to the following Spring XML
 * configuration:
 *
 * <pre class="code">
 * {@code
 * <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>
 * }</pre>
 *
 * The examples are equivalent save that in XML a <em>fixed-rate</em> period is used
 * instead of a custom <em>{@code Trigger}</em> implementation; this is because the
 * {@code task:} namespace {@code 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.<p>
 *
 * @author Chris Beams
 * @author Juergen Hoeller
 * @since 3.1
 * @see Scheduled
 * @see SchedulingConfiguration
 * @see SchedulingConfigurer
 * @see ScheduledTaskRegistrar
 * @see Trigger
 * @see ScheduledAnnotationBeanPostProcessor
 */
@Target(ElementType.TYPE)
@Retention(RetentionPolicy.RUNTIME)
@Import(SchedulingConfiguration.class)
@Documented
public @interface EnableScheduling {

}

从注释的第一句话就可以解答第一个问题,这个注解确实是启动前面所说的“计划任务”功能的,类似于用XML配置 Spring 时的 task 标签的作用。
可是这个执行“计划任务”的功能又是什么呢?
范例下面有解释:
当开发者在AppConfig类中使用了本注解,并在某个Task类中使用了@Schedule注解,那么被@Schedule注解的标注的方法就可以在指定时间自动执行。

那么这个“计划任务”其实被称为“定时任务”更为合适。

总结

关于@EnableScheduling,其实就是用来使@Schedule注解功能可用的注解。在 Spring Boot 的配置类中,标注上这个注解,就可以对项目中的方法某些方法使用@Schedule注解,将其变为定时自动执行。
但只有两种注解共同使用时,才能达到本注解应有的作用

相关文章

网友评论

      本文标题:每天一个Spring Boot注解学习——@EnableSche

      本文链接:https://www.haomeiwen.com/subject/zirxzttx.html