作者:男孩形式恋人 | 来源:互联网 | 2023-09-18 11:00
1、Quartz是OpenSymphony开源组织在Jobscheduling领域又一个开源项目,它可以与J2EE与J2SE应用程序相结合也可以单独使用。这里我介绍q
1、Quartz是OpenSymphony开源组织在Job scheduling领域又一个开源项目,它可以与J2EE与J2SE应用程序相结合也可以单独使用。这里我介绍quartz的两种方式。我这里搭建的框架是采用springboot、spring-data-jpa、mysql、quartz的方式来实现。
2、这里介绍的两种方式是:动态扫描的方式执行和注解的方式。
至于xml的配置方式可以参考:http://www.cnblogs.com/ll409546297/p/7157702.html
3、动态扫描的方式
1)基本的目录结构
2)需要的基础包:pom.xml
4.0.0 com.troy springbootquartz 1.0-SNAPSHOT
org.apache.maven.plugins maven-compiler-plugin 1.8 1.8
org.springframework.boot spring-boot-starter-parent 1.5.7.RELEASE org.springframework.boot spring-boot-starter-web 1.5.7.RELEASE org.springframework.boot spring-boot-starter-data-jpa 1.5.7.RELEASE org.quartz-scheduler quartz 2.3.0 org.quartz-scheduler quartz-jobs 2.3.0 mysql mysql-connector-java 5.1.9 org.springframework spring-context-support 4.3.11.RELEASE
3)基本的yml配置application.yml
server:port: 8080 spring:datasource:driver-class-name: com.mysql.jdbc.Driverurl: jdbc:mysql://localhost:3306/model?useUnicode=true&characterEncoding=utf8username: rootpassword: rootjpa:hibernate:ddl-auto: updateshow-sql: true
4)任务配置:TaskConfiguration.class
@Configuration @EnableScheduling public class TaskConfiguration {@Beanpublic SchedulerFactoryBean schedulerFactoryBean(){return new SchedulerFactoryBean();} }
5)实体需要的基础配置:ScheduleJob.class
@Entity @Table public class ScheduleJob {@Id@GeneratedValue(strategy = GenerationType.AUTO)private Long id;private String jobName;private String cronExpression;private String springId;private String methodName;private String jobStatus;public Long getId() {return id;}public void setId(Long id) {this.id = id;}public String getJobName() {return jobName;}public void setJobName(String jobName) {this.jobName = jobName;}public String getCronExpression() {return cronExpression;}public void setCronExpression(String cronExpression) {this.crOnExpression= cronExpression;}public String getSpringId() {return springId;}public void setSpringId(String springId) {this.springId = springId;}public String getMethodName() {return methodName;}public void setMethodName(String methodName) {this.methodName = methodName;}public String getJobStatus() {return jobStatus;}public void setJobStatus(String jobStatus) {this.jobStatus = jobStatus;} }
6)基础数据访问配置和数据访问层:
@NoRepositoryBean public interface BaseRepository extends PagingAndSortingRepository, JpaSpecificationExecutor { } public interface ScheduleJobRepository extends BaseRepository {List findAllByJobStatus(String jobStatus); } 7)SpringUtil.class
@Component public class SpringUtil implements BeanFactoryPostProcessor {private static ConfigurableListableBeanFactory beanFactory;public void postProcessBeanFactory(ConfigurableListableBeanFactory beanFactory) throws BeansException {this.beanFactory = beanFactory;}public static Object getBean(String name) {return beanFactory.getBean(name);}public static T getBean(Class clazz){return beanFactory.getBean(clazz);} }
8)任务的调度工厂(主要是实现具体的执行)QuartzFactory.class
public class QuartzFactory implements Job {@Overridepublic void execute(JobExecutionContext jobExecutionContext) throws JobExecutionException {//获取调度数据ScheduleJob scheduleJob = (ScheduleJob) jobExecutionContext.getMergedJobDataMap().get("scheduleJob");//获取对应的BeanObject object = SpringUtil.getBean(scheduleJob.getSpringId());try {//利用反射执行对应方法Method method = object.getClass().getMethod(scheduleJob.getMethodName());method.invoke(object);} catch (Exception e) {e.printStackTrace();}} }
9)具体的任务调度以及触发设置:TaskServiceImpl.class(略过接口)
@Service @Transactional public class TaskServiceImpl implements ITaskService {@Autowiredprivate SchedulerFactoryBean schedulerFactoryBean;@Autowiredprivate ScheduleJobRepository scheduleJobRepository;@Overridepublic void timingTask() {//查询数据库是否存在需要定时的任务List scheduleJobs = scheduleJobRepository.findAllByJobStatus("1");if (scheduleJobs != null) {scheduleJobs.forEach(this::execute);}}//添加任务private void execute(ScheduleJob scheduleJob){try {//声明调度器Scheduler scheduler = schedulerFactoryBean.getScheduler();//添加触发调度名称TriggerKey triggerKey = TriggerKey.triggerKey(scheduleJob.getJobName());//设置触发时间CronScheduleBuilder crOnScheduleBuilder= CronScheduleBuilder.cronSchedule(scheduleJob.getCronExpression());//触发建立Trigger trigger = TriggerBuilder.newTrigger().withIdentity(triggerKey).withSchedule(cronScheduleBuilder).build();//添加作业名称JobKey jobKey = JobKey.jobKey(scheduleJob.getJobName());//建立作业JobDetail jobDetail = JobBuilder.newJob(QuartzFactory.class).withIdentity(jobKey).build();//传入调度的数据,在QuartzFactory中需要使用jobDetail.getJobDataMap().put("scheduleJob",scheduleJob);//调度作业scheduler.scheduleJob(jobDetail,trigger);} catch (Exception e) {throw new RuntimeException(e);}} }
10)然后设置开机启动执行:TaskSchedule.class
@Component public class TaskSchedule implements CommandLineRunner{@Autowiredprivate ITaskService taskService;/*** 任务调度开始* @param strings* @throws Exception*/@Overridepublic void run(String... strings) throws Exception {System.out.println("任务调度开始==============任务调度开始");taskService.timingTask();System.out.println("任务调度结束==============任务调度结束");} }
这里基础的配置就算完成了,然后就是在数据库进行相关的配置,项目启动的时候就开始扫描对应的表来执行具体的任务。
这里我写了一下简单的例子来实现。
1)需要执行的方法:TaskInfoServiceImpl.class(略过接口)
@Service("taskInfo") @Transactional public class TaskInfoServiceImpl implements ITaskInfoService {@Overridepublic void execute() {System.out.println("任务执行开始===============任务执行开始");System.out.println(new Date());System.out.println("任务执行结束===============任务执行结束");} }
2)数据库的配置(我这里测试用的每分钟0点执行)
测试结果:
4、注解的方式
1)注解的方式相对动态配置来说简单的多,但是不便于管理。注解的方式需要的基础包,和上面基本上差不多
2)这里我写了一下简单的例子来实现:TaskExcuteServiceImpl.class
@Service @Transactional public class TaskExcuteServiceImpl implements ITaskExcuteService {@Scheduled(cron = "30 * * * * ?")@Overridepublic void excute() {System.out.println("注解执行开始==============注解执行开始");System.out.println(new Date());System.out.println("注解执行结束==============注解执行结束");} }
3)测试结果为:
文章参考:https://www.cnblogs.com/ll409546297/p/7793877.html