新闻资讯
SpringBoot2 整合ElasticJob框架(二)——定时任务加载
1、核心依赖包
这里使用2.0+的版本。
<dependency> <groupId>com.dangdang</groupId> <artifactId>elastic-job-lite-core</artifactId> <version>2.1.5</version> </dependency> <dependency> <groupId>com.dangdang</groupId> <artifactId>elastic-job-lite-spring</artifactId> <version>2.1.5</version> </dependency>
2、核心配置文件
这里主要配置一下Zookeeper中间件,分片和分片参数。
zookeeper: server: 127.0.0.1:2181 namespace: es-job job-config: cron: 0/10 * * * * ? shardCount: 1 shardItem: 0=A,1=B,2=C,3=D
3、自定义注解
看了官方的案例,没看到好用的注解,这里只能自己编写一个,基于案例的加载过程和核心API作为参考。
核心配置类:
com.dangdang.ddframe.job.lite.config.LiteJobConfiguration
根据自己想如何使用注解的思路,比如我只想注解定时任务名称和Cron表达式这两个功能,其他参数直接统一配置(这里可能是受QuartJob影响太深,可能根本就是想省事...)
@Inherited @Target({ElementType.TYPE}) @Retention(RetentionPolicy.RUNTIME) public @interface TaskJobSign { @AliasFor("cron") String value() default ""; @AliasFor("value") String cron() default ""; String jobName() default "";
}
4、作业案例
这里打印一些基本参数,对照配置和注解,一目了然。
@Component @TaskJobSign(cron = "0/5 * * * * ?",jobName = "Hello-Job") public class HelloJob implements SimpleJob { private static final Logger LOG = LoggerFactory.getLogger(HelloJob.class.getName()) ; @Override public void execute(ShardingContext shardingContext) {
LOG.info("当前线程: "+Thread.currentThread().getId());
LOG.info("任务分片:"+shardingContext.getShardingTotalCount());
LOG.info("当前分片:"+shardingContext.getShardingItem());
LOG.info("分片参数:"+shardingContext.getShardingParameter());
LOG.info("任务参数:"+shardingContext.getJobParameter());
}
}
5、加载定时任务
既然自定义注解,那加载过程自然也要自定义一下,读取自定义的注解,配置化,加入容器,然后初始化,等着任务执行就好。
@Configuration public class ElasticJobConfig { @Resource private ApplicationContext applicationContext ; @Resource private ZookeeperRegistryCenter zookeeperRegistryCenter; @Value("${job-config.cron}") private String cron ; @Value("${job-config.shardCount}") private int shardCount ; @Value("${job-config.shardItem}") private String shardItem ; /**
* 配置任务监听器
*/ @Bean public ElasticJobListener elasticJobListener() { return new TaskJobListener();
} /**
* 初始化配置任务
*/ @PostConstruct public void initTaskJob() {
Map<String, SimpleJob> jobMap = this.applicationContext.getBeansOfType(SimpleJob.class);
Iterator iterator = jobMap.entrySet().iterator(); while (iterator.hasNext()) { // 自定义注解管理 Map.Entry<String, SimpleJob> entry = (Map.Entry)iterator.next();
SimpleJob simpleJob = entry.getValue();
TaskJobSign taskJobSign = simpleJob.getClass().getAnnotation(TaskJobSign.class); if (taskJobSign != null){
String cron = taskJobSign.cron() ;
String jobName = taskJobSign.jobName() ; // 生成配置 SimpleJobConfiguration simpleJobConfiguration = new SimpleJobConfiguration(
JobCoreConfiguration.newBuilder(jobName, cron, shardCount)
.shardingItemParameters(shardItem).jobParameter(jobName).build(),
simpleJob.getClass().getCanonicalName());
LiteJobConfiguration liteJobConfiguration = LiteJobConfiguration.newBuilder(
simpleJobConfiguration).overwrite(true).build();
TaskJobListener taskJobListener = new TaskJobListener(); // 初始化任务 SpringJobScheduler jobScheduler = new SpringJobScheduler(
simpleJob, zookeeperRegistryCenter,
liteJobConfiguration, taskJobListener);
jobScheduler.init();
}
}
}
}
絮叨一句:不要疑问这些API是怎么知道,看下官方文档的案例,他们怎么使用这些核心API,这里就是照着写过来,就是多一步自定义注解类的加载过程。当然官方文档大致读一遍还是很有必要的。
补刀一句:如何快速学习一些组件的用法,首先找到官方文档,或者开源库Wiki,再不济ReadMe文档(如果都没有,酌情放弃,另寻其他),熟悉基本功能是否符合自己的需求,如果符合,就看下基本用法案例,熟悉API,最后就是研究自己需要的功能模块,个人经验来看,该过程是弯路最少,坑最少的。
6、任务监听
用法非常简单,实现ElasticJobListener接口。
@Component public class TaskJobListener implements ElasticJobListener { private static final Logger LOG = LoggerFactory.getLogger(TaskJobListener.class); private long beginTime = 0; @Override public void beforeJobExecuted(ShardingContexts shardingContexts) {
beginTime = System.currentTimeMillis();
LOG.info(shardingContexts.getJobName()+"===>开始...");
} @Override public void afterJobExecuted(ShardingContexts shardingContexts) { long endTime = System.currentTimeMillis();
LOG.info(shardingContexts.getJobName()+ "===>结束...[耗时:"+(endTime - beginTime)+"]");
}
}
絮叨一句:before和after执行前后,中间执行目标方法,标准的AOP切面思想,所以底层水平决定了对上层框架的理解速度,那本《Java编程思想》上的灰尘是不是该擦擦?
回复列表