SpringCloud学习心得(六) Springboot与Quartz集成

10 篇文章 0 订阅
9 篇文章 0 订阅

    SpringCloud还有很多的功能,请大家参照《史上最简单的SpringCloud教程》http://blog.csdn.net/forezp/article/details/69939114 方志朋的博客。

     本章开始,将陆续介绍集成quartz、Mybatis、多数据源、动态数据源、redis等功能,供大家参考。

     为了尽量简化系统规模,我们重新来建立一个项目,即一个eurkea,一个springboot项目。

     1、首先建立maven 的pom项目springcloud-parent进行统一的配置文件管理(配置文件分为开发、测试、UAT、PRD四个文件夹,默认用的dev的文件夹)

     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.0</modelVersion>
    <groupId>com.hotkidceo.parent</groupId>
    <artifactId>ceo-springcloud-parent</artifactId>
    <version>1.0.0-SNAPSHOT</version>
    <packaging>pom</packaging>
    <name>ceo-springcloud-parent</name>
    <description>parent</description>

    <parent>
        <groupId>org.springframework.boot</groupId>
        <artifactId>spring-boot-starter-parent</artifactId>
        <version>1.5.9.RELEASE</version>
        <relativePath />
    </parent>
    
    <properties>
        <project.build.sourceEncoding>UTF-8</project.build.sourceEncoding>
        <project.reporting.outputEncoding>UTF-8</project.reporting.outputEncoding>
        <java.version>1.8</java.version>
    </properties>
    
    <dependencyManagement>
        <dependencies>
            <dependency>
                <groupId>org.springframework.cloud</groupId>
                <artifactId>spring-cloud-dependencies</artifactId>
                <version>Dalston.SR5</version>
                <type>pom</type>
                <scope>import</scope>
            </dependency>
        </dependencies>
    </dependencyManagement>
    
    <profiles>
        <profile>
            <!-- 本地开发环境 -->
            <id>dev</id>
            <properties>
                <profiles.active>dev</profiles.active>
            </properties>
            <activation>
                <activeByDefault>true</activeByDefault>
            </activation>
        </profile>
        <profile>
            <!-- 测试环境 -->
            <id>test</id>
            <properties>
                <profiles.active>test</profiles.active>
            </properties>
        </profile>
        <profile>
            <!-- uat环境 -->
            <id>uat</id>
            <properties>
                <profiles.active>uat</profiles.active>
            </properties>
        </profile>
        <profile>
            <!-- 生产环境 -->
            <id>prd</id>
            <properties>
                <profiles.active>prd</profiles.active>
            </properties>
        </profile>
    </profiles>

    <build>
        <finalName>${project.artifactId}</finalName>
        <resources>
            <resource>
                <directory>src/main/resources</directory>
                <!-- 资源根目录排除各环境的配置,防止在生成目录中多余其它目录 -->
                <excludes>
                    <exclude>**/*.*</exclude>
                </excludes>
            </resource>
            <resource>
                <directory>src/main/resources/${profiles.active}</directory>
            </resource>
            <!-- 加入公用配置 -->
            <resource>
                <directory>src/main/resources/common</directory>
            </resource>
        </resources>
        <plugins>
            <plugin>
                <groupId>org.springframework.boot</groupId>
                <artifactId>spring-boot-maven-plugin</artifactId>
            </plugin>
        </plugins>
    </build>  
</project>

2、建立eureka-server,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.0</modelVersion>
    <groupId>com.wantceo.eurekaserver</groupId>
    <artifactId>ceo-eureka-server</artifactId>
    <version>0.0.1-SNAPSHOT</version>

    <parent>
        <groupId>com.hotkidceo.parent</groupId>
        <artifactId>ceo-springcloud-parent</artifactId>
        <version>1.0.0-SNAPSHOT</version>
    </parent>

    <dependencies>
        <!--eureka server -->
        <dependency>
            <groupId>org.springframework.cloud</groupId>
            <artifactId>spring-cloud-starter-eureka-server</artifactId>
        </dependency>

        <dependency>
            <groupId>org.springframework.boot</groupId>
            <artifactId>spring-boot-starter-actuator</artifactId>
        </dependency>
        
         <!-- spring boot test-->
        <dependency>
            <groupId>org.springframework.boot</groupId>
            <artifactId>spring-boot-starter-test</artifactId>
            <scope>test</scope>
        </dependency>
    </dependencies>

</project>

 

配置文件如下bootstrap.yml:

spring:
  application:
    name: ceo-eureka-server

server:
  port: 8601
 
eureka:
  instance:
    hostname: localhost
  server:
    enableSelfPreservation: true
    renewalPercentThreshold: 0.1
  client:
    #通过eureka.client.registerWithEureka:false和fetchRegistry:false来表明自己是一个eureka server.
    registerWithEureka: false
    fetchRegistry: false
 

编写一个启动类:

import org.springframework.boot.SpringApplication;
import org.springframework.boot.autoconfigure.SpringBootApplication;
import org.springframework.cloud.netflix.eureka.server.EnableEurekaServer;

@EnableEurekaServer
@SpringBootApplication
public class EurekaServer {

    public static void main(String[] args) {
        SpringApplication.run(EurekaServer.class, args);
    }

}

3、建立一个springboot的maven项目 cureka-client-test-quartz

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.0</modelVersion>
  <groupId>com.wantceo.eurekaclienttest2</groupId>
  <artifactId>ceo-eureka-client-test2</artifactId>
  <version>0.0.1-SNAPSHOT</version>
  <name>ceo-eureka-client-test2</name>
 
    <parent>
        <groupId>com.hotkidceo.parent</groupId>
        <artifactId>ceo-springcloud-parent</artifactId>
        <version>1.0.0-SNAPSHOT</version>
    </parent>

    <dependencies>
        <!--eureka server -->
        <dependency>
            <groupId>org.springframework.cloud</groupId>
            <artifactId>spring-cloud-starter-eureka-server</artifactId>
        </dependency>
        <!-- 访问数据库模块 -->
        <dependency>
            <groupId>org.springframework.boot</groupId>
            <artifactId>spring-boot-starter-data-jpa</artifactId>
        </dependency>
        <dependency>
            <groupId>org.springframework.boot</groupId>
            <artifactId>spring-boot-starter-web</artifactId>
        </dependency>
        <!-- MYSQL -->
        <dependency>
            <groupId>mysql</groupId>
            <artifactId>mysql-connector-java</artifactId>
        </dependency>
        <!-- 与数据库操作相关的依赖 -->
        <!-- Jdbc 模块 -->
        <dependency>
            <groupId>org.springframework.boot</groupId>
            <artifactId>spring-boot-starter-jdbc</artifactId>
        </dependency>
        <!-- mybatis -->
        <dependency>
            <groupId>org.mybatis.spring.boot</groupId>
            <artifactId>mybatis-spring-boot-starter</artifactId>
            <version>1.3.1</version>
        </dependency>
        <!-- druid 线程池模块 -->
        <dependency>
            <groupId>com.alibaba</groupId>
            <artifactId>druid</artifactId>
            <version>1.1.3</version>
        </dependency>
        <!-- quartz模块 -->
        <dependency>
            <groupId>org.quartz-scheduler</groupId>
            <artifactId>quartz</artifactId>
            <version>2.3.0</version>
        </dependency>
        <dependency>
            <groupId>org.quartz-scheduler</groupId>
            <artifactId>quartz-jobs</artifactId>
            <version>2.3.0</version>
        </dependency>
        <dependency>
            <groupId>org.springframework</groupId>
            <artifactId>spring-context-support</artifactId>
        </dependency>
        <!-- spring boot test-->
        <dependency>
            <groupId>org.springframework.boot</groupId>
            <artifactId>spring-boot-starter-test</artifactId>
            <scope>test</scope>
        </dependency>
    </dependencies>
</project>

配置文件:

spring:
  application:
    name: ceo-eureka-client-test-quartz
  datasource:
    driverClassName: com.mysql.jdbc.Driver
    url: jdbc:mysql://127.0.0.1/bpm?zeroDateTimeBehavior=convertToNull&amp;useUnicode=true&amp;characterEncoding=utf-8
    username: root
    password: 123  
 
server:
  port: 8641
 
eureka:
  client:
    serviceUrl:
      defaultZone: http://localhost:8601/eureka/  

在resources目录下建立common文件夹,并建立一个applicationContext.xml备用

配置文件目录如下

建立包domain、service、task、util,目录结构如下

在task包里面建立TestTask,增加两个方法 run() 和 run2()

import org.slf4j.Logger;
import org.slf4j.LoggerFactory;

public class TestTask {
    /** 日志对象 */
    private static final Logger LOG = LoggerFactory.getLogger(TestTask.class);

    public void run() {
        if (LOG.isInfoEnabled()) {
            LOG.info("测试任务线程开始执行");

            //new ScheduleJobService().getScheduleJob();
        }
    }

    public void run2() {
        if (LOG.isInfoEnabled()) {
            LOG.info("测试任务线程开始执行22222");

            //new ScheduleJobService().getScheduleJob();
        }

}

在domain里面建立job的实体类ScheduleJob

public class ScheduleJob {

    private String jobName;
    private String jobGroup;
    private String desc;
    private String jobStatus;
    private String cronExpression;
    public String getJobName() {
        return jobName;
    }
    public void setJobName(String jobName) {
        this.jobName = jobName;
    }
    public String getJobGroup() {
        return jobGroup;
    }
    public void setJobGroup(String jobGroup) {
        this.jobGroup = jobGroup;
    }
    public String getDesc() {
        return desc;
    }
    public void setDesc(String desc) {
        this.desc = desc;
    }
    public String getJobStatus() {
        return jobStatus;
    }
    public void setJobStatus(String jobStatus) {
        this.jobStatus = jobStatus;
    }
    public String getCronExpression() {
        return cronExpression;
    }
    public void setCronExpression(String cronExpression) {
        this.cronExpression = cronExpression;
    }    
}

在service包内新增QuartzJobFactory 继承 Job,用于

@DisallowConcurrentExecution
public class QuartzJobFactory implements Job{

    private static final Logger LOG = Logger.getLogger(QuartzJobFactory.class.getName());
    
    @Override
    public void execute(JobExecutionContext context) throws JobExecutionException {
        LOG.log(Level.INFO, "QuartzJobFactory execute start");
        ScheduleJob scheduleJob = (ScheduleJob)context.getMergedJobDataMap().get("scheduleJob");
        LOG.log(Level.INFO, "QuartzJobFactory execute end job name :" + scheduleJob.getJobName());
    }

}

@DisallowConcurrentExecution 禁止并发执行多个相同定义的JobDetail, 这个注解是加在Job类上的, 但意思并不是不能同时执行多个Job, 而是不能并发执行同一个Job Definition(由JobDetail定义), 但是可以同时执行多个不同的JobDetail, 举例说明,我们有一个Job类,叫做SayHelloJob, 并在这个Job上加了这个注解, 然后在这个Job上定义了很多个JobDetail, 如sayHelloToJoeJobDetail, sayHelloToMikeJobDetail, 那么当scheduler启动时, 不会并发执行多个sayHelloToJoeJobDetail或者sayHelloToMikeJobDetail, 但可以同时执行sayHelloToJoeJobDetail跟sayHelloToMikeJobDetail

 

创建ScheduleJobService 定时计划服务

public class ScheduleJobService {
    private static final Logger Logger = LoggerFactory.getLogger(ScheduleJobService.class);

    public void getScheduleJob(){

        try {
            SchedulerFactoryBean schedulerFactoryBean = SpringApplicationContextUtil.getBean("scheduler");
            Scheduler scheduler = schedulerFactoryBean.getScheduler();
            GroupMatcher<JobKey> matcher = GroupMatcher.anyJobGroup();
            Set<JobKey> jobKeys = scheduler.getJobKeys(matcher);        
            List<ScheduleJob> jobList = new ArrayList<ScheduleJob>();
            for (JobKey jobKey : jobKeys) {
                List<? extends Trigger> triggers = scheduler.getTriggersOfJob(jobKey);
                for (Trigger trigger : triggers) {
                    ScheduleJob job = new ScheduleJob();
                    job.setJobName(jobKey.getName());
                    job.setJobGroup(jobKey.getGroup());
                    job.setDesc("触发器:" + trigger.getKey());
                    Trigger.TriggerState triggerState = scheduler.getTriggerState(trigger.getKey());
                    job.setJobStatus(triggerState.name());
                    if (trigger instanceof CronTrigger) {
                        CronTrigger cronTrigger = (CronTrigger) trigger;
                        String cronExpression = cronTrigger.getCronExpression();
                        job.setCronExpression(cronExpression);
                    }
                    jobList.add(job);                                      
                }
            }

            for (ScheduleJob job : jobList) {
                Logger.info("计划列表,name:{},group:{},desc:{},status:{}",job.getJobName(),job.getJobGroup(),job.getDesc(),job.getJobStatus());
            }

        } catch (SchedulerException e) {
            Logger.error("SchedulerException", e);
        }
    }
}

 

applicationContext.xml的配置如下:

    <!-- 使用MethodInvokingJobDetailFactoryBean,任务类可以不实现Job接口,通过targetMethod指定调用方法-->
    <bean id="taskJob" class="com.hotkidceo.springcloud.task.TestTask"/>
    
    <bean id="jobDetail" class="org.springframework.scheduling.quartz.MethodInvokingJobDetailFactoryBean">
        <property name="group" value="job_work"/>
        <property name="name" value="job_work_name"/>
        <!--false表示等上一个任务执行完后再开启新的任务-->
        <property name="concurrent" value="false"/>
        <property name="targetObject">
            <ref bean="taskJob"/>
        </property>
        <property name="targetMethod">
            <value>run</value>
        </property>
    </bean>

    <bean id="jobDetail2" class="org.springframework.scheduling.quartz.MethodInvokingJobDetailFactoryBean">
        <property name="group" value="job_work"/>
        <property name="name" value="job_work_name2"/>
        <!--false表示等上一个任务执行完后再开启新的任务-->
        <property name="concurrent" value="false"/>
        <property name="targetObject">
            <ref bean="taskJob"/>
        </property>
        <property name="targetMethod">
            <value>run2</value>
        </property>
    </bean>
    
    <!--  调度触发器 -->
    <bean id="myTrigger"
        class="org.springframework.scheduling.quartz.CronTriggerFactoryBean">
        <property name="name" value="work_default_name"/>
        <property name="group" value="work_default"/>
        <property name="jobDetail">
            <ref bean="jobDetail" />
        </property>
        <property name="cronExpression">
            <value>0/15 * * * * ?</value>
        </property>
    </bean>
    
    <bean id="myTrigger2"
        class="org.springframework.scheduling.quartz.CronTriggerFactoryBean">
        <property name="name" value="work_default_name2"/>
        <property name="group" value="work_default"/>
        <property name="jobDetail">
            <ref bean="jobDetail2" />
        </property>
        <property name="cronExpression">
            <value>0/10 * * * * ?</value>
        </property>
    </bean>

    <!-- 调度工厂 -->
    <bean id="scheduler" class="org.springframework.scheduling.quartz.SchedulerFactoryBean">
        <property name="triggers">
            <list>
                <ref bean="myTrigger"/>
                <ref bean="myTrigger2"/>
            </list>
        </property>
    </bean>

最后建立一个启动类:

@EnableEurekaClient
@SpringBootApplication
@RestController
@ImportResource("applicationContext.xml")
public class EurekaserverClientOneApplication {
    public static void main(String[] args) {
        SpringApplication.run(EurekaserverClientOneApplication.class, args);
    }

}

启动eureka-server 再启动client,输出如下:

2018-07-26 11:04:40.003  INFO 39156 --- [eduler_Worker-3] com.hotkidceo.springcloud.task.TestTask  : 测试任务线程开始执行22222
2018-07-26 11:04:45.003  INFO 39156 --- [eduler_Worker-4] com.hotkidceo.springcloud.task.TestTask  : 测试任务线程开始执行
2018-07-26 11:04:50.003  INFO 39156 --- [eduler_Worker-5] com.hotkidceo.springcloud.task.TestTask  : 测试任务线程开始执行22222
2018-07-26 11:05:00.004  INFO 39156 --- [eduler_Worker-6] com.hotkidceo.springcloud.task.TestTask  : 测试任务线程开始执行
2018-07-26 11:05:00.005  INFO 39156 --- [eduler_Worker-7] com.hotkidceo.springcloud.task.TestTask  : 测试任务线程开始执行22222

 

小编的这个方法,基本是从网上找的,用的是配置文件的方法,目的是为了一个job类里面可以写多个任务方法。大家还可以参考下面这个文章

https://blog.csdn.net/zahngjialiang/article/details/78690932 Springboot实现quartz定时

 

源码地址:

parent

https://gitee.com/EricLoveMia/eric-springcloud-parent.git

server

https://gitee.com/EricLoveMia/eureka-server.git

client

https://gitee.com/EricLoveMia/eureka-client-test-quzrtz.git

sql在quzrtz项目中

  • 1
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值