本猿第一次写博客,写的不好勿喷
项目整体结构
springboot-elasticjob是定时任务
servicedemo是定时任务调用的服务(一个简单的服务这里不做过多介绍)
springboot-elasticjob
pom文件如下:
<project xmlns="http://maven.apache.org/POM/4.0.0"
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd">
<modelVersion>4.0.0modelVersion>
<groupId>cn.schedulergroupId>
<artifactId>springboot-elasticjobartifactId>
<version>1.0.0-SNAPSHOTversion>
<packaging>jarpackaging>
<name>springboot-elasticjobname>
<description>scheduler project for Spring Bootdescription>
<parent>
<groupId>org.springframework.bootgroupId>
<artifactId>spring-boot-starter-parentartifactId>
<version>2.0.3.RELEASEversion>
<relativePath />
parent>
<properties>
<project.build.sourceEncoding>UTF-8project.build.sourceEncoding>
<project.reporting.outputEncoding>UTF-8project.reporting.outputEncoding>
<spring-cloud.version>Finchley.RELEASEspring-cloud.version>
<java.version>1.8java.version>
<elastic-job.version>2.1.5elastic-job.version>
<commons-lang3.version>3.4commons-lang3.version>
<curator.version>2.10.0curator.version>
<druid.spring.boot.version>1.1.9druid.spring.boot.version>
<druid.version>1.1.9druid.version>
properties>
<dependencies>
<dependency>
<groupId>cn.demogroupId>
<artifactId>apiartifactId>
dependency>
<dependency>
<groupId>org.springframework.bootgroupId>
<artifactId>spring-boot-starter-actuatorartifactId>
dependency>
<dependency>
<groupId>org.springframework.cloudgroupId>
<artifactId>spring-cloud-starter-configartifactId>
dependency>
<dependency>
<groupId>org.springframework.cloudgroupId>
<artifactId>spring-cloud-starter-netflix-eureka-clientartifactId>
dependency>
<dependency>
<groupId>org.springframework.cloudgroupId>
<artifactId>spring-cloud-starter-netflix-hystrixartifactId>
dependency>
<dependency>
<groupId>org.springframework.cloudgroupId>
<artifactId>spring-cloud-starter-netflix-hystrix-dashboardartifactId>
dependency>
<dependency>
<groupId>org.springframework.bootgroupId>
<artifactId>spring-boot-starter-webartifactId>
dependency>
<dependency>
<groupId>org.springframework.cloudgroupId>
<artifactId>spring-cloud-starter-openfeignartifactId>
dependency>
<dependency>
<groupId>org.springframework.bootgroupId>
<artifactId>spring-boot-starter-webartifactId>
<exclusions>
<exclusion>
<groupId>ch.qos.logbackgroupId>
<artifactId>logback-coreartifactId>
exclusion>
<exclusion>
<groupId>org.apache.logging.log4jgroupId>
<artifactId>log4j-apiartifactId>
exclusion>
<exclusion>
<groupId>org.apache.logging.log4jgroupId>
<artifactId>log4j-to-slf4jartifactId>
exclusion>
<exclusion>
<groupId>ch.qos.logbackgroupId>
<artifactId>logback-classicartifactId>
exclusion>
<exclusion>
<groupId>org.slf4jgroupId>
<artifactId>slf4j-apiartifactId>
exclusion>
exclusions>
dependency>
<dependency>
<groupId>org.springframework.bootgroupId>
<artifactId>spring-boot-starter-loggingartifactId>
dependency>
<dependency>
<groupId>org.springframework.bootgroupId>
<artifactId>spring-boot-starter-jdbcartifactId>
<exclusions>
<exclusion>
<groupId>org.slf4jgroupId>
<artifactId>slf4j-apiartifactId>
exclusion>
exclusions>
dependency>
<dependency>
<groupId>mysqlgroupId>
<artifactId>mysql-connector-javaartifactId>
<scope>runtimescope>
dependency>
<dependency>
<groupId>com.alibabagroupId>
<artifactId>druid-spring-boot-starterartifactId>
dependency>
<dependency>
<groupId>org.springframework.bootgroupId>
<artifactId>spring-boot-starter-testartifactId>
<scope>testscope>
<exclusions>
<exclusion>
<groupId>org.slf4jgroupId>
<artifactId>slf4j-apiartifactId>
exclusion>
exclusions>
dependency>
<dependency>
<groupId>org.springframework.bootgroupId>
<artifactId>spring-boot-configuration-processorartifactId>
<optional>trueoptional>
dependency>
<dependency>
<groupId>org.apache.curatorgroupId>
<artifactId>curator-frameworkartifactId>
dependency>
<dependency>
<groupId>org.apache.curatorgroupId>
<artifactId>curator-clientartifactId>
<exclusions>
<exclusion>
<groupId>org.slf4jgroupId>
<artifactId>slf4j-apiartifactId>
exclusion>
exclusions>
dependency>
<dependency>
<groupId>org.apache.zookeepergroupId>
<artifactId>zookeeperartifactId>
<exclusions>
<exclusion>
<groupId>log4jgroupId>
<artifactId>log4jartifactId>
exclusion>
<exclusion>
<groupId>org.slf4jgroupId>
<artifactId>slf4j-apiartifactId>
exclusion>
<exclusion>
<groupId>org.slf4jgroupId>
<artifactId>slf4j-log4j12artifactId>
exclusion>
exclusions>
dependency>
<dependency>
<groupId>org.apache.curatorgroupId>
<artifactId>curator-recipesartifactId>
dependency>
<dependency>
<artifactId>elastic-job-common-coreartifactId>
<groupId>com.dangdanggroupId>
<exclusions>
<exclusion>
<groupId>org.slf4jgroupId>
<artifactId>slf4j-apiartifactId>
exclusion>
exclusions>
dependency>
<dependency>
<artifactId>elastic-job-lite-coreartifactId>
<groupId>com.dangdanggroupId>
dependency>
<dependency>
<artifactId>elastic-job-lite-springartifactId>
<groupId>com.dangdanggroupId>
dependency>
<dependency>
<groupId>org.apache.commonsgroupId>
<artifactId>commons-lang3artifactId>
dependency>
dependencies>
<dependencyManagement>
<dependencies>
<dependency>
<groupId>org.springframework.cloudgroupId>
<artifactId>spring-cloud-dependenciesartifactId>
<version>${spring-cloud.version}version>
<type>pomtype>
<scope>importscope>
dependency>
<dependency>
<groupId>org.apache.curatorgroupId>
<artifactId>curator-recipesartifactId>
<version>${curator.version}version>
dependency>
<dependency>
<groupId>org.apache.curatorgroupId>
<artifactId>curator-frameworkartifactId>
<version>${curator.version}version>
dependency>
<dependency>
<groupId>org.apache.curatorgroupId>
<artifactId>curator-clientartifactId>
<version>${curator.version}version>
dependency>
<dependency>
<groupId>org.apache.zookeepergroupId>
<artifactId>zookeeperartifactId>
<version>3.4.6version>
dependency>
<dependency>
<artifactId>elastic-job-common-coreartifactId>
<groupId>com.dangdanggroupId>
<version>${elastic-job.version}version>
dependency>
<dependency>
<artifactId>elastic-job-lite-coreartifactId>
<groupId>com.dangdanggroupId>
<version>${elastic-job.version}version>
dependency>
<dependency>
<artifactId>elastic-job-lite-springartifactId>
<groupId>com.dangdanggroupId>
<version>${elastic-job.version}version>
dependency>
<dependency>
<groupId>com.alibabagroupId>
<artifactId>druid-spring-boot-starterartifactId>
<version>${druid.spring.boot.version}version>
dependency>
<dependency>
<groupId>cn.demogroupId>
<artifactId>apiartifactId>
<version>1.0.0-SNAPSHOTversion>
dependency>
dependencies>
dependencyManagement>
<build>
<plugins>
<plugin>
<groupId>org.springframework.bootgroupId>
<artifactId>spring-boot-maven-pluginartifactId>
plugin>
plugins>
build>
<distributionManagement>
<repository>
<id>nexus.kelaile-releaseid>
<url>http://127.0.0.1:8081/nexus/content/repositories/releases/url>
repository>
<snapshotRepository>
<id>nexus.kelaile-snapshotid>
<url>http://127.0.0.1:8081/nexus/content/repositories/snapshots/url>
snapshotRepository>
distributionManagement>
<repositories>
<repository>
<id>nexus.kelaile-releaseid>
<url>http://127.0.0.1:8081/nexus/content/groups/public/url>
<releases>
<enabled>trueenabled>
releases>
<snapshots>
<enabled>trueenabled>
<updatePolicy>alwaysupdatePolicy>
snapshots>
repository>
repositories>
project>
配置信息:
server:
port: 8080
spring:
profiles:
active: dev
application:
name: springboot-elasticjob
##配置中心
cloud:
config:
username: username
password: password
profile: ${spring.profiles.active}
discovery:
service-id: config-server
enabled: true
##数据源
datasource:
type: com.alibaba.druid.pool.DruidDataSource
driver-class-name: com.mysql.jdbc.Driver
url: jdbc:mysql://localhost:3306/elastic_job?useSSL=false&useUnicode=true&characterEncoding=utf-8&allowMultiQueries=true
username: root
password: 123456
druid:
initial-size: 3
max-active: 10
min-idle: 5
max-wait: 600000
validation-query: SELECT 1
test-on-borrow: true
test-on-return: false
test-while-idle: true
time-between-eviction-runs-millis: 600000
min-evictable-idle-time-millis: 600000
filters: stat,wall
info:
app_name: ${spring.application.name}
##注册中心
eureka:
client:
service-url:
defaultZone: http://username:password@127.0.0.1:9011/eureka/
##zookeeper配置
demo:
elasticjob:
zk-config:
serverLists: localhost:2181
namespace: elastic-job-lite-demo
baseSleepTimeMilliseconds: 1000
maxSleepTimeMilliseconds: 3000
maxRetries: 4
digest: 'password'
#DEMO-PROVIDER.ribbon.listOfServers: localhost:8088
#ribbon.eureka.enabled: false
首先看config包下的配置
JobEventConfig为JobEventRdbConfiguration配置数据源:
/*
* Copyright 1999-2015 dangdang.com.
*
* 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 cn.demo.scheduler.config;
import com.dangdang.ddframe.job.event.JobEventConfiguration;
import com.dangdang.ddframe.job.event.rdb.JobEventRdbConfiguration;
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;
import javax.annotation.Resource;
import javax.sql.DataSource;
/**
* 为job配置数据源
*
* @author xing
*
*/
@Configuration
public class JobEventConfig {
@Resource
private DataSource dataSource;
@Bean
public JobEventConfiguration jobEventConfiguration() {
return new JobEventRdbConfiguration(dataSource);
}
}
RegistryCenterConfig配置zookeeper注册信息:
/*
* Copyright 1999-2015 dangdang.com.
*
* 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 cn.demo.scheduler.config;
import org.springframework.boot.context.properties.ConfigurationProperties;
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;
@Configuration
@ConfigurationProperties(prefix = "demo.elasticjob.zk-config")
public class RegistryCenterConfig {
/**
* 连接Zookeeper服务器的列表. 包括IP地址和端口号. 多个地址用逗号分隔. 如: host1:2181,host2:2181
*/
private String serverLists;
/**
* 命名空间.
*/
private String namespace;
/**
* 等待重试的间隔时间的初始值. 单位毫秒.
*/
private int baseSleepTimeMilliseconds;
/**
* 等待重试的间隔时间的最大值. 单位毫秒.
*/
private int maxSleepTimeMilliseconds;
/**
* 最大重试次数.
*/
private int maxRetries;
/**
* 登录权限
*/
private String digest;
@Bean(initMethod = "init")
public ZookeeperRegistryCenter zookeeperRegistryCenter() {
ZookeeperConfiguration zookeeperConfiguration = new ZookeeperConfiguration(serverLists, namespace);
zookeeperConfiguration.setMaxRetries(maxRetries);
zookeeperConfiguration.setBaseSleepTimeMilliseconds(baseSleepTimeMilliseconds);
zookeeperConfiguration.setMaxSleepTimeMilliseconds(maxSleepTimeMilliseconds);
zookeeperConfiguration.setDigest(digest);
return new ZookeeperRegistryCenter(zookeeperConfiguration);
}
public String getServerLists() {
return serverLists;
}
public void setServerLists(String serverLists) {
this.serverLists = serverLists;
}
public String getNamespace() {
return namespace;
}
public void setNamespace(String namespace) {
this.namespace = namespace;
}
public int getBaseSleepTimeMilliseconds() {
return baseSleepTimeMilliseconds;
}
public void setBaseSleepTimeMilliseconds(int baseSleepTimeMilliseconds) {
this.baseSleepTimeMilliseconds = baseSleepTimeMilliseconds;
}
public int getMaxSleepTimeMilliseconds() {
return maxSleepTimeMilliseconds;
}
public void setMaxSleepTimeMilliseconds(int maxSleepTimeMilliseconds) {
this.maxSleepTimeMilliseconds = maxSleepTimeMilliseconds;
}
public int getMaxRetries() {
return maxRetries;
}
public void setMaxRetries(int maxRetries) {
this.maxRetries = maxRetries;
}
public String getDigest() {
return digest;
}
public void setDigest(String digest) {
this.digest = digest;
}
}
接下来是每个定时任务的配置,这里我是把所有的配置放在了数据库表结构如下:
elastic_job_config任务配置表,elastic_job_config_log每次修改时进行备份
CREATE TABLE `elastic_job_config` (
`id` int(11) NOT NULL AUTO_INCREMENT,
`job_name` varchar(255) NOT NULL COMMENT '作业名称',
`cron` varchar(50) NOT NULL COMMENT 'cron表达式,用于控制作业触发时间',
`sharding_total_count` int(3) NOT NULL COMMENT '作业分片总数',
`sharding_item_parameters` varchar(255) DEFAULT NULL COMMENT '分片序列,列号从0开始,不可大于或等于作业分片总数.如:0=a,1=b,2=c',
`job_parameter` varchar(255) DEFAULT NULL COMMENT '作业自定义参数',
`failover` enum('false','true') DEFAULT 'true' COMMENT '是否开启任务执行失效转移',
`misfire` enum('false','true') DEFAULT 'true' COMMENT '是否开启错过任务重新执行',
`description` varchar(255) DEFAULT NULL COMMENT '作业描述信息',
`job_class` varchar(255) NOT NULL COMMENT '作业实现类',
`streaming_process` enum('false','true') DEFAULT 'true' COMMENT '是否流式处理数据(只有Dataflow类型支持)',
`job_config` text,
PRIMARY KEY (`id`),
UNIQUE KEY `jobName` (`job_name`)
) ENGINE=InnoDB AUTO_INCREMENT=21 DEFAULT CHARSET=utf8;
INSERT INTO `elastic_job_config` (
`id`,
`job_name`,
`cron`,
`sharding_total_count`,
`sharding_item_parameters`,
`job_parameter`,
`failover`,
`misfire`,
`description`,
`job_class`,
`streaming_process`,
`job_config`
)
VALUES
(
'1',
'DemoSimpleJob',
'1 1 1 * * ?',
'1',
'',
'',
'true',
'true',
'测试定时任务',
'cn.demo.scheduler.task.DemoSimpleJob',
'true',
''
);
CREATE TABLE `elastic_job_config_log` (
`id` int(11) NOT NULL AUTO_INCREMENT,
`job_name` varchar(255) NOT NULL COMMENT '作业名称',
`cron` varchar(50) NOT NULL COMMENT 'cron表达式,用于控制作业触发时间',
`sharding_total_count` int(3) NOT NULL COMMENT '作业分片总数',
`sharding_item_parameters` varchar(255) DEFAULT NULL COMMENT '分片序列,列号从0开始,不可大于或等于作业分片总数.如:0=a,1=b,2=c',
`job_parameter` varchar(255) DEFAULT NULL COMMENT '作业自定义参数',
`failover` enum('false','true') DEFAULT 'true' COMMENT '是否开启任务执行失效转移',
`misfire` enum('false','true') DEFAULT 'true' COMMENT '是否开启错过任务重新执行',
`description` varchar(255) DEFAULT NULL COMMENT '作业描述信息',
`job_class` varchar(255) NOT NULL COMMENT '作业实现类',
`streaming_process` enum('false','true') DEFAULT 'true' COMMENT '是否流式处理数据(只有Dataflow类型支持)',
`job_config` text,
`create_time` datetime DEFAULT NULL,
PRIMARY KEY (`id`)
) ENGINE=InnoDB AUTO_INCREMENT=27 DEFAULT CHARSET=utf8;
任务加载流程:在项目启动时读取数据库配置进行配置,当然也可以做成在页面上添加配置时同时向zookeeper中注册任务信息。
因为数据库里配置的是定时任务的全类名,这里通过反射进行实例化,无法使用spring的依赖注入对定时任务类中的属性进行初始化,所以我是用反射对有@Resource和@Autowired的属性赋值。
由于业务需求,我们需要添加一个额外的参数,数据库列名“job_config”,这个完全可以不要。
package cn.demo.scheduler.runner;
import java.lang.annotation.Annotation;
import java.lang.reflect.Field;
import java.util.HashMap;
import java.util.List;
import java.util.Map;
import javax.annotation.Resource;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.boot.CommandLineRunner;
import org.springframework.stereotype.Component;
import com.dangdang.ddframe.job.api.ElasticJob;
import com.dangdang.ddframe.job.api.dataflow.DataflowJob;
import com.dangdang.ddframe.job.api.simple.SimpleJob;
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.simple.SimpleJobConfiguration;
import com.dangdang.ddframe.job.event.JobEventConfiguration;
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;
import cn.demo.scheduler.dao.ElasticJobConfigDao;
import cn.demo.scheduler.entity.ElasticJobConfigBean;
import cn.demo.scheduler.util.BeanTools;
/**
* 定时任务配置
*
* @author xing
*
*/
@Component
public class ElasticJobRunner implements CommandLineRunner {
private Logger log = LoggerFactory.getLogger(ElasticJobRunner.class);
private static final Map<String, String> JOB_CONFIG_MAP = new HashMap<>();
@Resource
private ZookeeperRegistryCenter zookeeperRegistryCenter;
@Resource
private JobEventConfiguration jobEventConfiguration;
@Resource
private ElasticJobConfigDao elasticJobConfigDao;
/**
* 根据jobName获取配置
*
* @param jobName
* @return
*/
public static String getJobConfig(String jobName) {
return JOB_CONFIG_MAP.get(jobName);
}
/**
* 更改jobConfig
*
* @param jobName
* @param jobConfig
*/
public static void setJobConfig(String jobName, String jobConfig) {
JOB_CONFIG_MAP.put(jobName, jobConfig);
}
/**
* 注入任务
*
* @param elasticJobConfigBean
*/
@SuppressWarnings("unchecked")
private void registryJob(ElasticJobConfigBean elasticJobConfigBean) {
try {
Class<? extends ElasticJob> jobClass = (Class<? extends ElasticJob>) Class
.forName(elasticJobConfigBean.getJobClass());
ElasticJob elasticJob = getInstance(jobClass);
SpringJobScheduler jobScheduler = jobScheduler(elasticJob, jobClass, elasticJobConfigBean);
jobScheduler.init();
log.info("初始化定时任务 {} ", elasticJobConfigBean.toString());
} catch (Exception e) {
log.error("注册Job出错:{} ", elasticJobConfigBean.toString(), e);
}
}
/**
* 通过反射对有@Resource和@Autowired的属性赋值
*
* @param jobClass
* @return
* @throws InstantiationException
* @throws IllegalAccessException
*/
private ElasticJob getInstance(Class<? extends ElasticJob> jobClass)
throws InstantiationException, IllegalAccessException {
Field[] declaredFields = jobClass.getDeclaredFields();
ElasticJob newInstance = jobClass.newInstance();
for (Field field : declaredFields) {
Annotation[] annotations = field.getAnnotations();
if (annotations == null || annotations.length == 0) {
continue;
}
boolean flag = false;
for (Annotation annotation : annotations) {
Class<? extends Annotation> annotationType = annotation.annotationType();
if (annotationType.equals(Resource.class) || annotationType.equals(Autowired.class)) {
flag = true;
break;
}
}
if (flag) {
field.setAccessible(true);
field.set(newInstance, BeanTools.getBean(field.getType()));
}
}
return newInstance;
}
/**
* 注册SpringJobScheduler
*
* @param elasticJob
* @param jobClass
* @param elasticJobConfigBean
* @return
*/
private SpringJobScheduler jobScheduler(ElasticJob elasticJob, Class<? extends ElasticJob> jobClass,
ElasticJobConfigBean elasticJobConfigBean) {
LiteJobConfiguration build = LiteJobConfiguration.newBuilder(jobConfiguration(elasticJob, elasticJobConfigBean))
.overwrite(true).build();
SpringJobScheduler springJobScheduler = new SpringJobScheduler(elasticJob, zookeeperRegistryCenter, build,
jobEventConfiguration);
return springJobScheduler;
}
/**
* job配置
*
* @param elasticJob
* @param elasticJobConfigBean
* @return
*/
private JobTypeConfiguration jobConfiguration(final ElasticJob elasticJob,
ElasticJobConfigBean elasticJobConfigBean) {
JobCoreConfiguration jobCoreConfiguration = JobCoreConfiguration
.newBuilder(elasticJobConfigBean.getJobName(), elasticJobConfigBean.getCron(),
elasticJobConfigBean.getShardingTotalCount())
.shardingItemParameters(elasticJobConfigBean.getShardingItemParameters())
.misfire(Boolean.valueOf(elasticJobConfigBean.getMisfire()))
.description(elasticJobConfigBean.getDescription())
.failover(Boolean.valueOf(elasticJobConfigBean.getFailover()))
.jobParameter(elasticJobConfigBean.getJobParameter())
.build();
if (elasticJob instanceof SimpleJob) {
return new SimpleJobConfiguration(jobCoreConfiguration, elasticJob.getClass().getCanonicalName());
}
if (elasticJob instanceof DataflowJob) {
return new DataflowJobConfiguration(jobCoreConfiguration, elasticJob.getClass().getCanonicalName(),
Boolean.valueOf(elasticJobConfigBean.getStreamingProcess()));
}
throw new RuntimeException("未知类型定时任务:" + elasticJob.getClass().getName());
}
@Override
public void run(String... args) throws Exception {
List<ElasticJobConfigBean> elasticJobConfigList = elasticJobConfigDao.getElasticJobConfigList();
if (elasticJobConfigList == null || elasticJobConfigList.size() == 0) {
return;
}
elasticJobConfigList.forEach(elasticJobConfig -> {
registryJob(elasticJobConfig);
JOB_CONFIG_MAP.put(elasticJobConfig.getJobName(), elasticJobConfig.getJobConfig());
});
}
}
启动类上要注意扫描FeignClient
package cn.demo.scheduler;
import org.springframework.boot.SpringApplication;
import org.springframework.cloud.client.SpringCloudApplication;
import org.springframework.cloud.openfeign.EnableFeignClients;
import org.springframework.context.annotation.ComponentScan;
@SpringCloudApplication
@ComponentScan(value = { "cn.demo.scheduler"})
@EnableFeignClients(basePackages = { "cn.demo.api" })
public class ScheduleApplication {
public static void main(String[] args) {
SpringApplication.run(ScheduleApplication.class, args);
}
}
定时任务类DemoSimpleJob:
package cn.demo.scheduler.task;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.beans.factory.annotation.Autowired;
import com.dangdang.ddframe.job.api.ShardingContext;
import com.dangdang.ddframe.job.api.simple.SimpleJob;
import cn.demo.api.TestBean;
import cn.demo.api.TestService;
public class DemoSimpleJob implements SimpleJob {
private Logger log = LoggerFactory.getLogger(DemoSimpleJob.class);
@Autowired
private TestService testService;
@Override
public void execute(ShardingContext shardingContext) {
String jobParameter = shardingContext.getJobParameter();
log.info("test--------------------{}", jobParameter);
TestBean testBean = new TestBean();
testBean.setId("123");
testBean.setName("Hello World!");
TestBean test = testService.test(testBean);
log.info(test.toString());
}
}
这里的controller、service、dao是定时任务配置的增删改查,不做过多介绍。
接下来就是去当当的开源定时任务管理上配置定时任务:
源码见:https://github.com/dcw2020520/springboot-elasticjob