spring在进行扩展的时候,最常用的就是@Autowired 自动装配或Module-wired模块装配(@EnableXXX),Module-wired是将模块整体引入工程中,然后通过几个自定义注解完成应用;
step1. 创建springboot工程rabbit-task引入依赖pom.xml
<properties>
<java.version>1.8</java.version>
<elastic-job.version>2.1.4</elastic-job.version>
</properties>
<dependencies>
<!-- spring boot dependency -->
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter</artifactId>
</dependency>
<!-- elastic-job dependency -->
<dependency>
<groupId>com.dangdang</groupId>
<artifactId>elastic-job-lite-core</artifactId>
<version>${elastic-job.version}</version>
</dependency>
<dependency>
<groupId>com.dangdang</groupId>
<artifactId>elastic-job-lite-spring</artifactId>
<version>${elastic-job.version}</version>
</dependency>
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-configuration-processor</artifactId>
<optional>true</optional>
</dependency>
</dependencies>
step2. 创建JobParserAutoConfigure自动装配类
import org.springframework.context.annotation.Configuration;
@Configuration
public class JobParserAutoConfigure {
}
step3. 创建spring.fatories自动装配加载文件
# Auto Configure
org.springframework.boot.autoconfigure.EnableAutoConfiguration=\
com.cc.rabbit.task.autoconfigure.JobParserAutoConfigure
如此rabbit-task构建完成后,引入其他工程时,就会自动找到spring.fatories文件,并将由@Configuration声明的JobParserAutoConfigure做相关的初始化或其他操作,此装配为无条件默认装配。
step4. 通过@Conditional做条件装配:常用@ConditionalOnProperty()进行条件设置,其条件代表需要在application.properties或*.properties文件中配置规定的参数,才启动装配;
通过elastic-job配置来举个例子,elastic-job的使用需要依赖zookeeper配置,将namespace、serverLists作为必须配置参数作为装配条件,同时也是构造条件(官方API设定),其他配置项通过JobZookeeperProperties类进行封装,传入ZookeeperRegistryCenter完成注册中心初始化:
import org.springframework.boot.autoconfigure.condition.ConditionalOnProperty;
import org.springframework.boot.context.properties.EnableConfigurationProperties;
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;
import com.dangdang.ddframe.job.reg.zookeeper.ZookeeperConfiguration;
import com.dangdang.ddframe.job.reg.zookeeper.ZookeeperRegistryCenter;
/**
* @ConditionalOnProperty(prefix = "elastic.job.zk", name = {"namespace","serverLists"},matchIfMissing = false)
* 引入rabbit-task的工程必须在application.properties中配置elastic.job.zk.namespace和
* elastic.job.zk.serverLists两个属性,才会装配成功,matchIfMissing = false如果没有配置两个参数
* 那么rabbit-task就不会加载,此处为强约定;
* @EnableConfigurationProperties(JobZookeeperProperties.class),当@ConditionalOnProperty验证通过后,将elastic.job.zk
* 为前缀的配置参数读到JobZookeeperProperties中;然后初始化registryCenter。
*/
@Configuration
@ConditionalOnProperty(prefix = "elastic.job.zk", name = {"namespace","serverLists"},matchIfMissing = false)
@EnableConfigurationProperties(JobZookeeperProperties.class)
public class JobParserAutoConfigure {
//初始化RegistryCenter
@Bean(initMethod = "init")
public ZookeeperRegistryCenter zookeeperRegistryCenter(JobZookeeperProperties jobZookeeperProperties) {//如果将ZookeeperRegistryCenter注入到spring容器,那么Bean的名字就是方法名字(约定)
ZookeeperConfiguration zkConfig = new ZookeeperConfiguration(jobZookeeperProperties.getServerLists(),
jobZookeeperProperties.getNamespace());
zkConfig.setBaseSleepTimeMilliseconds(zkConfig.getBaseSleepTimeMilliseconds());
zkConfig.setMaxSleepTimeMilliseconds(zkConfig.getMaxSleepTimeMilliseconds());
zkConfig.setConnectionTimeoutMilliseconds(zkConfig.getConnectionTimeoutMilliseconds());
zkConfig.setSessionTimeoutMilliseconds(zkConfig.getSessionTimeoutMilliseconds());
zkConfig.setMaxRetries(zkConfig.getMaxRetries());
zkConfig.setDigest(zkConfig.getDigest());
System.out.println("初始化job注册中心配置成功"+zkConfig.getNamespace());
return new ZookeeperRegistryCenter(zkConfig);
}
}
import org.springframework.boot.context.properties.ConfigurationProperties;
import lombok.Data;
/**
* 装载配置参数
* 装载任何封装组件属性参数时,都要参考官方进行对应,必要配置项扫描加载,
* 非必要配置项要设定默认值,范围要根据官方给定的有效范围进行设定;
* 必要配置与非必要配置区分,其一根据业务设定,其二官方在属性说明中
* 会有是否为构造器注入,是就为必要配置,否即为非必要配置。
*/
@Data
@ConfigurationProperties(prefix = "elastic.job.zk")
public class JobZookeeperProperties {
private String namespace;
private String serverLists;
private int maxRetries = 3;
private int connectionTimeoutMilliseconds = 15000;
private int sessionTimeoutMilliseconds = 60000;
private int baseSleepTimeMilliseconds = 1000;
private int maxSleepTimeMilliseconds = 3000;
private String digest = "";
}
step5. 自定义模块装配注解@EnableElasticJob:模块装配注解,除了自定义注解的四个基本属性,还必须要使用@Import注解,将自定义的配置类JobParserAutoConfigure引入;
package com.cc.rabbit.task.annotation;
import java.lang.annotation.Documented;
import java.lang.annotation.ElementType;
import java.lang.annotation.Inherited;
import java.lang.annotation.Retention;
import java.lang.annotation.RetentionPolicy;
import java.lang.annotation.Target;
import org.springframework.context.annotation.Import;
import com.cc.rabbit.task.autoconfigure.JobParserAutoConfigure;
/**
* 1 注解四个基本属性设置;
* 2 模块注入注解:@Import(JobParserAutoConfigure.class)
*/
@Target(ElementType.TYPE)
@Retention(RetentionPolicy.RUNTIME)
@Documented
@Inherited
@Import(JobParserAutoConfigure.class)
public @interface EnableElasticJob {
}
step6. 自定义@ElasticJobConfig,进行es-job的基础API参数构建,规避每次创建任务都需要构建job类,实现注解式配置,当需要一个job,那么按照此配置项加载一个类,自动解析;
package com.cc.rabbit.task.annotation;
import java.lang.annotation.ElementType;
import java.lang.annotation.Retention;
import java.lang.annotation.RetentionPolicy;
import java.lang.annotation.Target;
/**
* 封装elasticjob官方属性,依据官方api给出的属性参数进行声明;
*/
@Target(ElementType.TYPE)
@Retention(RetentionPolicy.RUNTIME)
public @interface ElasticJobConfig {
/*JobCoreConfiguration属性详细说明*/
String jobName(); //elasticjob的名称
String cron() default "";
int shardingTotalCount() default 1;
String shardingItemParameters() default "";
String jobParameter() default "";
boolean failover() default false;
boolean misfire() default true;
String description() default "";
/*DataflowJobConfiguration属性详细说明---是否流式处理数据*/
boolean streamingProcess() default false;
/*ScriptJobConfiguration属性详细说明---脚本型作业*/
String scriptCommandLine() default "";
/*LiteJobConfiguration属性详细说明---作业运行监控配置*/
boolean monitorExecution() default false;
public int monitorPort() default -1; //must
public int maxTimeDiffSeconds() default -1; //must
public String jobShardingStrategyClass() default ""; //must
public int reconcileIntervalMinutes() default 10; //must
public String eventTraceRdbDataSource() default ""; //must
/*job:simple命名空间属性详细说明*/
public boolean disabled() default false; //must
boolean overwrite() default false;
public String distributedListener() default "";
public long startedTimeoutMilliseconds() default Long.MAX_VALUE; //must
public long completedTimeoutMilliseconds() default Long.MAX_VALUE; //must
public String jobExceptionHandler() default "com.dangdang.ddframe.job.executor.handler.impl.DefaultJobExceptionHandler";
public String executorServiceHandler() default "com.dangdang.ddframe.job.executor.handler.impl.DefaultExecutorServiceHandler";
}
step7. 解析自定义@ElasticJobConfig:JobParserAutoConfigure中创建ElasticJobConfParser来解析注解;
package com.cc.rabbit.task.autoconfigure;
import org.springframework.boot.autoconfigure.condition.ConditionalOnProperty;
import org.springframework.boot.context.properties.EnableConfigurationProperties;
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;
import com.cc.rabbit.task.parser.ElasticJobConfParser;
import com.dangdang.ddframe.job.reg.zookeeper.ZookeeperConfiguration;
import com.dangdang.ddframe.job.reg.zookeeper.ZookeeperRegistryCenter;
/**
* @ConditionalOnProperty(prefix = "elastic.job.zk", name = {"namespace","serverLists"},matchIfMissing = false)
* 引入rabbit-task的工程必须在application.properties中配置elastic.job.zk.namespace和
* elastic.job.zk.serverLists两个属性,才会装配成功,matchIfMissing = false如果没有配置两个参数
* 那么rabbit-task就不会加载,此处为强约定;
* @EnableConfigurationProperties(JobZookeeperProperties.class),当@ConditionalOnProperty验证通过后,将elastic.job.zk
* 为前缀的配置参数读到JobZookeeperProperties中;然后初始化registryCenter。
*/
@Configuration
@ConditionalOnProperty(prefix = "elastic.job.zk", name = {"namespace","serverLists"},matchIfMissing = false)
@EnableConfigurationProperties(JobZookeeperProperties.class)
public class JobParserAutoConfigure {
//初始化RegistryCenter
@Bean(initMethod = "init")
public ZookeeperRegistryCenter zookeeperRegistryCenter(JobZookeeperProperties jobZookeeperProperties) {//如果将ZookeeperRegistryCenter注入到spring容器,那么Bean的名字就是方法名字(约定)
ZookeeperConfiguration zkConfig = new ZookeeperConfiguration(jobZookeeperProperties.getServerLists(),
jobZookeeperProperties.getNamespace());
zkConfig.setBaseSleepTimeMilliseconds(zkConfig.getBaseSleepTimeMilliseconds());
zkConfig.setMaxSleepTimeMilliseconds(zkConfig.getMaxSleepTimeMilliseconds());
zkConfig.setConnectionTimeoutMilliseconds(zkConfig.getConnectionTimeoutMilliseconds());
zkConfig.setSessionTimeoutMilliseconds(zkConfig.getSessionTimeoutMilliseconds());
zkConfig.setMaxRetries(zkConfig.getMaxRetries());
zkConfig.setDigest(zkConfig.getDigest());
System.out.println("初始化job注册中心配置成功"+zkConfig.getNamespace());
return new ZookeeperRegistryCenter(zkConfig);
}
@Bean
public ElasticJobConfParser elasticJobConfParser(JobZookeeperProperties jobZookeeperProperties,ZookeeperRegistryCenter zookeeperRegistryCenter) {
return new ElasticJobConfParser(jobZookeeperProperties,zookeeperRegistryCenter);
}
}
package com.cc.rabbit.task.parser;
import com.cc.rabbit.task.autoconfigure.JobZookeeperProperties;
import com.dangdang.ddframe.job.reg.zookeeper.ZookeeperRegistryCenter;
public class ElasticJobConfParser {
private JobZookeeperProperties jobZookeeperProperties;
private ZookeeperRegistryCenter zookeeperRegistryCenter;
public ElasticJobConfParser(JobZookeeperProperties jobZookeeperProperties,
ZookeeperRegistryCenter zookeeperRegistryCenter) {
this.jobZookeeperProperties = jobZookeeperProperties;
this.zookeeperRegistryCenter = zookeeperRegistryCenter;
}
}
logic:
1. 应用时添加@EnableElasticJob注解;
2.@EnableElasticJob加载JobParserAutoConfigure配置;
3.JobParserAutoConfigure先判断@ConditionalOnProperty条件是否满足,如果满足会将application.properties中配置的参数全部读入JobZookeeperProperties对象;
4.初始化zk(ZookeeperRegistryCenter);
5.初始化es-job(ElasticJobConfParser),ElasticJobConfParser专注解析@ElasticJobConfig注解;
step8. 通过ElasticJobTypeEunm(eunm枚举)来定义es-job的三种作业类型:
package com.cc.rabbit.task.enums;
public enum ElasticJobTypeEunm {
SIMPLE("SimpleJob","简单类型job"),
DATAFLOW("DataflowJob","流式类型job"),
SCRIPT("ScriptJob","脚本类型job");
private String type;
private String desc;
private ElasticJobTypeEunm(String type,String desc) {
this.type = type;
this.desc = desc;
}
public String getType() {
return type;
}
public void setType(String type) {
this.type = type;
}
public String getDesc() {
return desc;
}
public void setDesc(String desc) {
this.desc = desc;
}
}
step9. ElasticJobConfParser解析es-job的时机,ElasticJobConfParser与spring直接存在某种依赖关系,那么对于ElasticJobConfParser解析es-job的恰当时机就要在spring提供的一些机制中根据业务场景进行确定,此处举例为分布式定时任务的基础封装,在诸多场景中最为合理的是当应用服务都启动以后,即所有的springBean加载完成后,做es-job的解析,定时任务场景本身就是对于应用服务进行定时作业的一种机制,所有必须保证规划的应用已经存在,才能生效;初始化过程为,先初始化es-job相关的JobCoreConfiguration、SimpleJobConfiguration及LiteJobConfiguration,然后在构建SpringJobScheduler;对比前期代码实现的集成方式,逻辑为相反;
package com.cc.rabbit.task.parser;
import java.util.Iterator;
import java.util.List;
import java.util.Map;
import org.springframework.beans.factory.config.BeanDefinition;
import org.springframework.beans.factory.support.BeanDefinitionBuilder;
import org.springframework.beans.factory.support.DefaultListableBeanFactory;
import org.springframework.beans.factory.support.ManagedList;
import org.springframework.boot.context.event.ApplicationReadyEvent;
import org.springframework.context.ApplicationContext;
import org.springframework.context.ApplicationListener;
import org.springframework.util.StringUtils;
import com.cc.rabbit.task.annotation.ElasticJobConfig;
import com.cc.rabbit.task.autoconfigure.JobZookeeperProperties;
import com.cc.rabbit.task.enums.ElasticJobTypeEunm;
import com.dangdang.ddframe.job.config.JobCoreConfiguration;
import com.dangdang.ddframe.job.config.JobTypeConfiguration;
import com.dangdang.ddframe.job.config.dataflow.DataflowJobConfiguration;
import com.dangdang.ddframe.job.config.script.ScriptJobConfiguration;
import com.dangdang.ddframe.job.config.simple.SimpleJobConfiguration;
import com.dangdang.ddframe.job.event.rdb.JobEventRdbConfiguration;
import com.dangdang.ddframe.job.executor.handler.JobProperties;
import com.dangdang.ddframe.job.lite.config.LiteJobConfiguration;
import com.dangdang.ddframe.job.lite.spring.api.SpringJobScheduler;
import com.dangdang.ddframe.job.reg.zookeeper.ZookeeperRegistryCenter;
public class ElasticJobConfParser implements ApplicationListener<ApplicationReadyEvent>{
private JobZookeeperProperties jobZookeeperProperties;
private ZookeeperRegistryCenter zookeeperRegistryCenter;
public ElasticJobConfParser(JobZookeeperProperties jobZookeeperProperties,
ZookeeperRegistryCenter zookeeperRegistryCenter) {
this.jobZookeeperProperties = jobZookeeperProperties;
this.zookeeperRegistryCenter = zookeeperRegistryCenter;
}
@Override
public void onApplicationEvent(ApplicationReadyEvent event) {
try {
//获取应用上下文
ApplicationContext applicationContext = event.getApplicationContext();
//获取所有添加@ElasticJobConfig注解的bean
Map<String, Object> beanMap = applicationContext.getBeansWithAnnotation(ElasticJobConfig.class);
//循环所有Bean,独立配置,初始化相关内容
for(Iterator<?> it = beanMap.values().iterator();it.hasNext();) {
Object confBean = it.next();
Class<?> clazz = confBean.getClass();
//如果是一个子类,匿名或带有“$”符号,将真正的名字取出复制给clazz
if(clazz.getName().indexOf("$") > 0) {
String className = clazz.getName();
//从0截取到$前为真正的类名
clazz = Class.forName(className.substring(0,className.indexOf("$")));
}
/* 获取接口类型,用于判断任务类型(简单类型、流式、脚本)
* 此处简写,取第一个interface;
* 正常生产中类可能实现多个interface,要遍历判断;
*/
String jobTypeName = clazz.getInterfaces()[0].getSimpleName();
//获取ElasticJobConfig的配置项
ElasticJobConfig conf = clazz.getAnnotation(ElasticJobConfig.class);
String jobClass = clazz.getName();
//防止重复:使用Namespace加jobname组合
//String jobName = conf.jobName();
String jobName = this.jobZookeeperProperties.getNamespace() +"."+ conf.jobName();
String cron = conf.cron();
String shardingItemParameters = conf.shardingItemParameters();
String description = conf.description();
String jobParameter = conf.jobParameter();
String jobExceptionHandler = conf.jobExceptionHandler();
String executorServiceHandler = conf.executorServiceHandler();
String jobShardingStrategyClass = conf.jobShardingStrategyClass();
String eventTraceRdbDataSource = conf.eventTraceRdbDataSource();
String scriptCommandLine = conf.scriptCommandLine();
boolean failover = conf.failover();
boolean misfire = conf.misfire();
boolean overwrite = conf.overwrite();
boolean disabled = conf.disabled();
boolean monitorExecution = conf.monitorExecution();
boolean streamingProcess = conf.streamingProcess();
int shardingTotalCount = conf.shardingTotalCount();
int monitorPort = conf.monitorPort();
int maxTimeDiffSeconds = conf.maxTimeDiffSeconds();
int reconcileIntervalMinutes = conf.reconcileIntervalMinutes();
// 1 先将当当网的esjob相关configuration实例化(然后在与spring做集成)
JobCoreConfiguration coreConfig = JobCoreConfiguration
.newBuilder(jobName, cron, shardingTotalCount)
.shardingItemParameters(shardingItemParameters)
.description(description)
.failover(failover)
.jobParameter(jobParameter)
.misfire(misfire)
.jobProperties(JobProperties.JobPropertiesEnum.JOB_EXCEPTION_HANDLER.getKey(), jobExceptionHandler)
.jobProperties(JobProperties.JobPropertiesEnum.EXECUTOR_SERVICE_HANDLER.getKey(), executorServiceHandler)
.build();
/* 2 确定创建任务的类型
* 通过判断继承接口的名字与ElasticJobTypeEunm枚举中定义的属性值是否一致来判断任务类型;
*/
JobTypeConfiguration typeConfig = null;
if(ElasticJobTypeEunm.SIMPLE.getType().equals(jobTypeName)) {
typeConfig = new SimpleJobConfiguration(coreConfig, jobClass);
}
if(ElasticJobTypeEunm.DATAFLOW.getType().equals(jobTypeName)) {
typeConfig = new DataflowJobConfiguration(coreConfig, jobClass, streamingProcess);
}
if(ElasticJobTypeEunm.SCRIPT.getType().equals(jobTypeName)) {
typeConfig = new ScriptJobConfiguration(coreConfig, scriptCommandLine);
}
// 3 初始化LiteJobConfiguration
LiteJobConfiguration jobConfig = LiteJobConfiguration
.newBuilder(typeConfig)
.overwrite(overwrite)
.disabled(disabled)
.monitorPort(monitorPort)
.monitorExecution(monitorExecution)
.maxTimeDiffSeconds(maxTimeDiffSeconds)
.jobShardingStrategyClass(jobShardingStrategyClass)
.reconcileIntervalMinutes(reconcileIntervalMinutes)
.build();
// 4 创建一个spring的beanDefiniton
BeanDefinitionBuilder factory = BeanDefinitionBuilder.rootBeanDefinition(SpringJobScheduler.class);
factory.setInitMethodName("init");
factory.setScope("prototype"); //多例(非单例)
// // -1.添加bean构造参数,相当于添加自己的真实的任务实现类
if (!ElasticJobTypeEunm.SCRIPT.getType().equals(jobTypeName)) {
factory.addConstructorArgValue(confBean);
}
// -2.添加注册中心
factory.addConstructorArgValue(this.zookeeperRegistryCenter);
// -3.添加LiteJobConfiguration
factory.addConstructorArgValue(jobConfig);
// -4.如果有eventTraceRdbDataSource 则也进行添加
if (StringUtils.hasText(eventTraceRdbDataSource)) {
BeanDefinitionBuilder rdbFactory = BeanDefinitionBuilder.rootBeanDefinition(JobEventRdbConfiguration.class);
rdbFactory.addConstructorArgReference(eventTraceRdbDataSource);
factory.addConstructorArgValue(rdbFactory.getBeanDefinition());
}
// 5.添加监听
List<?> elasticJobListeners = getTargetElasticJobListeners(conf);
factory.addConstructorArgValue(elasticJobListeners);
// 6.把factory也就是 SpringJobScheduler注入到Spring容器中
DefaultListableBeanFactory defaultListableBeanFactory = (DefaultListableBeanFactory) applicationContext.getAutowireCapableBeanFactory();
String registerBeanName = conf.jobName() + "SpringJobScheduler";
defaultListableBeanFactory.registerBeanDefinition(registerBeanName, factory.getBeanDefinition());
SpringJobScheduler scheduler = (SpringJobScheduler)applicationContext.getBean(registerBeanName);
scheduler.init();
System.out.println("启动elastic-job作业: " + jobName);
}
System.out.println("共计启动elastic-job作业数量为:"+beanMap.values().size()+"个");
} catch (Exception e) {
System.out.println("elasticjob 启动异常, 系统强制退出");
System.exit(1);
}
}
private List<BeanDefinition> getTargetElasticJobListeners(ElasticJobConfig conf) {
List<BeanDefinition> result = new ManagedList<BeanDefinition>(2);
String listeners = conf.listener();
if (StringUtils.hasText(listeners)) {
BeanDefinitionBuilder factory = BeanDefinitionBuilder.rootBeanDefinition(listeners);
factory.setScope("prototype");
result.add(factory.getBeanDefinition());
}
String distributedListeners = conf.distributedListener();
long startedTimeoutMilliseconds = conf.startedTimeoutMilliseconds();
long completedTimeoutMilliseconds = conf.completedTimeoutMilliseconds();
if (StringUtils.hasText(distributedListeners)) {
BeanDefinitionBuilder factory = BeanDefinitionBuilder.rootBeanDefinition(distributedListeners);
factory.setScope("prototype");
factory.addConstructorArgValue(Long.valueOf(startedTimeoutMilliseconds));
factory.addConstructorArgValue(Long.valueOf(completedTimeoutMilliseconds));
result.add(factory.getBeanDefinition());
}
return result;
}
}
step10. 测试es-job组件封装:
1.创建测试项目rabbit-es-job并将rabbit-task依赖引入:
2.配置application.properties,配置必要的两个参数属性namespace和serverLists
server.port=8881
elastic.job.zk.namespace=elastic-job
elastic.job.zk.serverLists=192.168.85.140:2182,192.168.85.142:2182,192.168.85.141:2182
#mysql数据源
spring.datasource.url=jdbc:mysql://localhost:3306/elasticjob?useUnicode=true&characterEncoding=utf-8&verifyServerCertificate=false&useSSL=false&requireSSL=false
spring.datasource.driver-class-name=com.mysql.jdbc.Driver
spring.datasource.username=root
spring.datasource.password=root
3.将自定义注解@EnableElasticJob添加到Application
package com.cc.es;
import org.springframework.boot.SpringApplication;
import org.springframework.boot.autoconfigure.SpringBootApplication;
import com.cc.rabbit.task.annotation.EnableElasticJob;
@EnableElasticJob
@SpringBootApplication
public class Application {
public static void main(String[] args) {
SpringApplication.run(Application.class, args);
}
}
4.创建定时任务TestJob与DemoJob做为测试:必须添加@Component注解将测试类注入spring容器;通过@ElasticJobConfig自定义注解配置定时任务参数;<必须开启虚拟机的zookeeper作为测试>
package com.cc.es.task.test;
import org.springframework.stereotype.Component;
import com.cc.rabbit.task.annotation.ElasticJobConfig;
import com.dangdang.ddframe.job.api.ShardingContext;
import com.dangdang.ddframe.job.api.simple.SimpleJob;
@Component
@ElasticJobConfig(
jobName = "com.cc.es.task.test.TestJob",
cron = "0/5 * * * * ?",
description = "测试定时任务",
overwrite = true,
shardingTotalCount = 5
)
public class TestJob implements SimpleJob{
@Override
public void execute(ShardingContext shardingContext) {
System.out.println("-----执行Test job!");
}
}
package com.cc.es.task.test;
import org.springframework.stereotype.Component;
import com.cc.rabbit.task.annotation.ElasticJobConfig;
import com.dangdang.ddframe.job.api.ShardingContext;
import com.dangdang.ddframe.job.api.simple.SimpleJob;
@Component
@ElasticJobConfig(
jobName = "com.cc.es.task.test.DemoJob",
cron = "0/10 * * * * ?",
description = "样例测试定时任务",
overwrite = true,
shardingTotalCount = 5
)
public class DemoJob implements SimpleJob{
@Override
public void execute(ShardingContext shardingContext) {
System.out.println("-----执行Demo Job!");
}
}
5.运行Application测试输出:
ElasticJob基础组件封装完成,测试通过。