### 1、适配方案

* [solon-scheduling-simple](/article/359)
* [solon-scheduling-quartz](/article/360)	

两个方案，体验上总体差不多。一些细节上的差别，具体看插件的使用说明。

### 2、使用预览

启动类上，增加启用注解

```java
// 启用 Scheduled 注解的任务
@EnableScheduling
public class JobApp {
    public static void main(String[] args) {
        Solon.start(JobApp.class, args);
    }
}
```

注解在类上

```java
// 基于 Runnable 接口的模式
@Scheduled(fixedRate = 1000 * 3)
public class Job1 implements Runnable {
    @Override
    public void run() {
        System.out.println("我是 Job1 （3s）");
    }
}
```

或者，注解在组件的方法上

```java
@Component
public class JobBean {
    @Scheduled(fixedRate = 1000 * 3)
    public void job11(){
        System.out.println("我是 job11 （3s）");
    }
}
```

增加拦截处理（如果有需要？），v2.7.2 后支持：

```java
@Slf4j
@Component
public class JobInterceptorImpl implements JobInterceptor {
    @Override
    public void doIntercept(Job job, JobHandler handler) throws Throwable {
        long start = System.currentTimeMillis();
        try {
            handler.handle(job.getContext());
        } catch (Throwable e) {
            //记录日志
            TagsMDC.tag0("job");
            TagsMDC.tag1(job.getName());
            log.error("{}", e);

            throw e; //别吃掉
        } finally {
            //记录一个内部处理的花费时间
            long timespan = System.currentTimeMillis() - start;
            System.out.println("JobInterceptor: job=" + job.getName());
        }
    }
}
```

### 3、注解 Scheduled 属性说明

| 属性 | 说明 |  备注 |  
| -------- | -------- |  -------- | 
| cron     | 支持7位（秒，分，时，日期ofM，月，星期ofW，年）     | 将并行执行 |
| zone     | 时区：+08 或 CET 或 Asia/Shanghai     |  配合 cron 使用 |
| | | |
| fixedRate      | 固定频率毫秒数（大于 0 时，cron 会失效）                    | 将并行执行 |
| fixedDelay     | 固定延时毫秒数（大于 0 时，cron 和 fixedRate 会失效） | 将串行执行 |
| initialDelay     | 初次执行延时毫秒数    | 配合 fixedRate 或 fixedDelay 使用 |

不同的适配插件，支持程序略有不同。比如 quartz 不支持 fixedDelay 和 initialDelay（具体看相关插件页）。


### 4、Scheduled 的策略选择参考



| 策略 | 属性选择 | 备注 |
| -------- | -------- | -------- |
| 固定频率     | fixedRate     | 旧任务如果未完成，频率时间到了，新任务会开始（可能会有多任务同时运行）     |
| 固定延时     | fixedDelay     | 旧任务完成后，延时一段时间后，再开始新任务（只会有一个任务运行）     |
| Cron 表达式     | cron     | 时间到就会运行（与 fixedRate 像）     |



### 5、内部管理接口 IJobManager

IJobManager 是内部管理接口，会在应用容器启动时启动，启动后状态会变成：`isStarted() == true`。

```java
public interface IJobManager extends Lifecycle {
    //任务添加（不需要再 jobStart）
    JobHolder jobAdd(String name, Scheduled scheduled, JobHandler handler);
    //任务是否存在
    boolean jobExists(String name);
    //任务获取
    JobHolder jobGet(String name);
    //任务移除（会自动停止）
    void jobRemove(String name);
    //任务开始（jobStop 后，才需要执行 jobStart 重新启动）
    void jobStart(String name, Map<String, String> data) throws ScheduledException;
    //任务停止
    void jobStop(String name) throws ScheduledException;
    //是否已启动
    boolean isStarted();
}
```

### 5、手动控制示例

```java
//也可以被注入（注入，v2.5.6 后支持）
IJobManager jobManager = JobManager.getInstance();

//添加任务
if(jobManager.jobExists("demo") == false){
    jobManager.jobAdd("demo" , new ScheduledAnno().fixedRate(1000), (ctx)->{
       System.out.printl("Hello job");
    });
}

//移除任务
jobManager.jobRemove("demo");
```