註明:本文只是在項目中使用的過程中解決問題才提出的解決方案,可能並不適配全部人的項目解決方案,僅做參考!前端
附上博主在Github上的一個項目,不定時更新喲-->歡迎fork、star。歡迎關注博主喲: https://github.com/yarcl/SpringbootDemovue
注意:該項目當中全部內容均在項目當中存在,安裝完數據、配置好後,直接使用便可。java
包含內容:git
a、雙數據源配置github
b、quartz任務調度spring
c、vue前端訪問數據綁定sql
......數據庫
一、Springboot集成Quartz,首先必需要完成的功能是搭建Springboot的項目。保證項目能夠正常運行。dom
目錄結構以下圖所示:ide
二、加入Quartz的依賴關係
<dependency> <groupId>org.quartz-scheduler</groupId> <artifactId>quartz</artifactId> <version>2.2.3</version> </dependency> <dependency> <groupId>org.quartz-scheduler</groupId> <artifactId>quartz-jobs</artifactId> <version>2.2.3</version> </dependency>
三、加入依賴以後,在resources目錄下增長quartz.properties文件,文件內容以下:
org.quartz.jobStore.useProperties=false org.quartz.jobStore.tablePrefix=QRTZ_ org.quartz.jobStore.isClustered=true org.quartz.jobStore.clusterCheckinInterval=5000 org.quartz.jobStore.misfireThreshold=600000 org.quartz.jobStore.txIsolationLevelReadCommitted=true org.quartz.jobStore.class=org.quartz.impl.jdbcjobstore.JobStoreTX org.quartz.jobStore.driverDelegateClass=org.quartz.impl.jdbcjobstore.StdJDBCDelegate org.quartz.scheduler.instanceName=ClusterQuartz org.quartz.scheduler.instanceId=AUTO org.quartz.scheduler.rmi.export=false org.quartz.scheduler.rmi.proxy=false org.quartz.scheduler.wrapJobExecutionInUserTransaction=false org.quartz.threadPool.class=org.quartz.simpl.SimpleThreadPool org.quartz.threadPool.threadCount=5 org.quartz.threadPool.threadPriority=9 org.quartz.threadPool.threadsInheritContextClassLoaderOfInitializingThread=true # 解決屢次觸發問題 org.quartz.jobStore.acquireTriggersWithinLock=true
四、當前配置須要進行數據存儲觸發內容和觸發時間節點,須要建立quartz所須要的表,固然也能夠去官網進行下載後查看對應的腳本文件:
CREATE TABLE `QRTZ_BLOB_TRIGGERS` (
`SCHED_NAME` varchar(120) NOT NULL, `TRIGGER_NAME` varchar(200) NOT NULL, `TRIGGER_GROUP` varchar(200) NOT NULL, `BLOB_DATA` blob, PRIMARY KEY (`SCHED_NAME`,`TRIGGER_NAME`,`TRIGGER_GROUP`), KEY `SCHED_NAME` (`SCHED_NAME`,`TRIGGER_NAME`,`TRIGGER_GROUP`), CONSTRAINT `QRTZ_BLOB_TRIGGERS_ibfk_1` FOREIGN KEY (`SCHED_NAME`, `TRIGGER_NAME`, `TRIGGER_GROUP`) REFERENCES `QRTZ_TRIGGERS` (`SCHED_NAME`, `TRIGGER_NAME`, `TRIGGER_GROUP`) ) ENGINE=InnoDB DEFAULT CHARSET=utf8mb4; CREATE TABLE `QRTZ_CALENDARS` ( `SCHED_NAME` varchar(120) NOT NULL, `CALENDAR_NAME` varchar(200) NOT NULL, `CALENDAR` blob NOT NULL, PRIMARY KEY (`SCHED_NAME`,`CALENDAR_NAME`) ) ENGINE=InnoDB DEFAULT CHARSET=utf8mb4; CREATE TABLE `QRTZ_CRON_TRIGGERS` ( `SCHED_NAME` varchar(120) NOT NULL, `TRIGGER_NAME` varchar(200) NOT NULL, `TRIGGER_GROUP` varchar(200) NOT NULL, `CRON_EXPRESSION` varchar(120) NOT NULL, `TIME_ZONE_ID` varchar(80) DEFAULT NULL, PRIMARY KEY (`SCHED_NAME`,`TRIGGER_NAME`,`TRIGGER_GROUP`), CONSTRAINT `QRTZ_CRON_TRIGGERS_ibfk_1` FOREIGN KEY (`SCHED_NAME`, `TRIGGER_NAME`, `TRIGGER_GROUP`) REFERENCES `QRTZ_TRIGGERS` (`SCHED_NAME`, `TRIGGER_NAME`, `TRIGGER_GROUP`) ) ENGINE=InnoDB DEFAULT CHARSET=utf8mb4; CREATE TABLE `QRTZ_FIRED_TRIGGERS` ( `SCHED_NAME` varchar(120) NOT NULL, `ENTRY_ID` varchar(95) NOT NULL, `TRIGGER_NAME` varchar(200) NOT NULL, `TRIGGER_GROUP` varchar(200) NOT NULL, `INSTANCE_NAME` varchar(200) NOT NULL, `FIRED_TIME` bigint(13) NOT NULL, `SCHED_TIME` bigint(13) NOT NULL, `PRIORITY` int(11) NOT NULL, `STATE` varchar(16) NOT NULL, `JOB_NAME` varchar(200) DEFAULT NULL, `JOB_GROUP` varchar(200) DEFAULT NULL, `IS_NONCONCURRENT` varchar(1) DEFAULT NULL, `REQUESTS_RECOVERY` varchar(1) DEFAULT NULL, PRIMARY KEY (`SCHED_NAME`,`ENTRY_ID`), KEY `IDX_QRTZ_FT_TRIG_INST_NAME` (`SCHED_NAME`,`INSTANCE_NAME`), KEY `IDX_QRTZ_FT_INST_JOB_REQ_RCVRY` (`SCHED_NAME`,`INSTANCE_NAME`,`REQUESTS_RECOVERY`), KEY `IDX_QRTZ_FT_J_G` (`SCHED_NAME`,`JOB_NAME`,`JOB_GROUP`), KEY `IDX_QRTZ_FT_JG` (`SCHED_NAME`,`JOB_GROUP`), KEY `IDX_QRTZ_FT_T_G` (`SCHED_NAME`,`TRIGGER_NAME`,`TRIGGER_GROUP`), KEY `IDX_QRTZ_FT_TG` (`SCHED_NAME`,`TRIGGER_GROUP`) ) ENGINE=InnoDB DEFAULT CHARSET=utf8mb4; CREATE TABLE `QRTZ_JOB_DETAILS` ( `SCHED_NAME` varchar(120) NOT NULL, `JOB_NAME` varchar(200) NOT NULL, `JOB_GROUP` varchar(200) NOT NULL, `DESCRIPTION` varchar(250) DEFAULT NULL, `JOB_CLASS_NAME` varchar(250) NOT NULL, `IS_DURABLE` varchar(1) NOT NULL, `IS_NONCONCURRENT` varchar(1) NOT NULL, `IS_UPDATE_DATA` varchar(1) NOT NULL, `REQUESTS_RECOVERY` varchar(1) NOT NULL, `JOB_DATA` blob, PRIMARY KEY (`SCHED_NAME`,`JOB_NAME`,`JOB_GROUP`), KEY `IDX_QRTZ_J_REQ_RECOVERY` (`SCHED_NAME`,`REQUESTS_RECOVERY`), KEY `IDX_QRTZ_J_GRP` (`SCHED_NAME`,`JOB_GROUP`) ) ENGINE=InnoDB DEFAULT CHARSET=utf8mb4; CREATE TABLE `QRTZ_LOCKS` ( `SCHED_NAME` varchar(120) NOT NULL, `LOCK_NAME` varchar(40) NOT NULL, PRIMARY KEY (`SCHED_NAME`,`LOCK_NAME`) ) ENGINE=InnoDB DEFAULT CHARSET=utf8mb4; CREATE TABLE `QRTZ_PAUSED_TRIGGER_GRPS` ( `SCHED_NAME` varchar(120) NOT NULL, `TRIGGER_GROUP` varchar(200) NOT NULL, PRIMARY KEY (`SCHED_NAME`,`TRIGGER_GROUP`) ) ENGINE=InnoDB DEFAULT CHARSET=utf8mb4; CREATE TABLE `QRTZ_SCHEDULER_STATE` ( `SCHED_NAME` varchar(120) NOT NULL, `INSTANCE_NAME` varchar(200) NOT NULL, `LAST_CHECKIN_TIME` bigint(13) NOT NULL, `CHECKIN_INTERVAL` bigint(13) NOT NULL, PRIMARY KEY (`SCHED_NAME`,`INSTANCE_NAME`) ) ENGINE=InnoDB DEFAULT CHARSET=utf8mb4; CREATE TABLE `QRTZ_SIMPLE_TRIGGERS` ( `SCHED_NAME` varchar(120) NOT NULL, `TRIGGER_NAME` varchar(200) NOT NULL, `TRIGGER_GROUP` varchar(200) NOT NULL, `REPEAT_COUNT` bigint(7) NOT NULL, `REPEAT_INTERVAL` bigint(12) NOT NULL, `TIMES_TRIGGERED` bigint(10) NOT NULL, PRIMARY KEY (`SCHED_NAME`,`TRIGGER_NAME`,`TRIGGER_GROUP`), CONSTRAINT `QRTZ_SIMPLE_TRIGGERS_ibfk_1` FOREIGN KEY (`SCHED_NAME`, `TRIGGER_NAME`, `TRIGGER_GROUP`) REFERENCES `QRTZ_TRIGGERS` (`SCHED_NAME`, `TRIGGER_NAME`, `TRIGGER_GROUP`) ) ENGINE=InnoDB DEFAULT CHARSET=utf8mb4; CREATE TABLE `QRTZ_SIMPROP_TRIGGERS` ( `SCHED_NAME` varchar(120) NOT NULL, `TRIGGER_NAME` varchar(200) NOT NULL, `TRIGGER_GROUP` varchar(200) NOT NULL, `STR_PROP_1` varchar(512) DEFAULT NULL, `STR_PROP_2` varchar(512) DEFAULT NULL, `STR_PROP_3` varchar(512) DEFAULT NULL, `INT_PROP_1` int(11) DEFAULT NULL, `INT_PROP_2` int(11) DEFAULT NULL, `LONG_PROP_1` bigint(20) DEFAULT NULL, `LONG_PROP_2` bigint(20) DEFAULT NULL, `DEC_PROP_1` decimal(13,4) DEFAULT NULL, `DEC_PROP_2` decimal(13,4) DEFAULT NULL, `BOOL_PROP_1` varchar(1) DEFAULT NULL, `BOOL_PROP_2` varchar(1) DEFAULT NULL, PRIMARY KEY (`SCHED_NAME`,`TRIGGER_NAME`,`TRIGGER_GROUP`), CONSTRAINT `QRTZ_SIMPROP_TRIGGERS_ibfk_1` FOREIGN KEY (`SCHED_NAME`, `TRIGGER_NAME`, `TRIGGER_GROUP`) REFERENCES `QRTZ_TRIGGERS` (`SCHED_NAME`, `TRIGGER_NAME`, `TRIGGER_GROUP`) ) ENGINE=InnoDB DEFAULT CHARSET=utf8mb4; CREATE TABLE `QRTZ_TRIGGERS` ( `SCHED_NAME` varchar(120) NOT NULL, `TRIGGER_NAME` varchar(200) NOT NULL, `TRIGGER_GROUP` varchar(200) NOT NULL, `JOB_NAME` varchar(200) NOT NULL, `JOB_GROUP` varchar(200) NOT NULL, `DESCRIPTION` varchar(250) DEFAULT NULL, `NEXT_FIRE_TIME` bigint(13) DEFAULT NULL, `PREV_FIRE_TIME` bigint(13) DEFAULT NULL, `PRIORITY` int(11) DEFAULT NULL, `TRIGGER_STATE` varchar(16) NOT NULL, `TRIGGER_TYPE` varchar(8) NOT NULL, `START_TIME` bigint(13) NOT NULL, `END_TIME` bigint(13) DEFAULT NULL, `CALENDAR_NAME` varchar(200) DEFAULT NULL, `MISFIRE_INSTR` smallint(2) DEFAULT NULL, `JOB_DATA` blob, PRIMARY KEY (`SCHED_NAME`,`TRIGGER_NAME`,`TRIGGER_GROUP`), KEY `IDX_QRTZ_T_J` (`SCHED_NAME`,`JOB_NAME`,`JOB_GROUP`), KEY `IDX_QRTZ_T_JG` (`SCHED_NAME`,`JOB_GROUP`), KEY `IDX_QRTZ_T_C` (`SCHED_NAME`,`CALENDAR_NAME`), KEY `IDX_QRTZ_T_G` (`SCHED_NAME`,`TRIGGER_GROUP`), KEY `IDX_QRTZ_T_STATE` (`SCHED_NAME`,`TRIGGER_STATE`), KEY `IDX_QRTZ_T_N_STATE` (`SCHED_NAME`,`TRIGGER_NAME`,`TRIGGER_GROUP`,`TRIGGER_STATE`), KEY `IDX_QRTZ_T_N_G_STATE` (`SCHED_NAME`,`TRIGGER_GROUP`,`TRIGGER_STATE`), KEY `IDX_QRTZ_T_NEXT_FIRE_TIME` (`SCHED_NAME`,`NEXT_FIRE_TIME`), KEY `IDX_QRTZ_T_NFT_ST` (`SCHED_NAME`,`TRIGGER_STATE`,`NEXT_FIRE_TIME`), KEY `IDX_QRTZ_T_NFT_MISFIRE` (`SCHED_NAME`,`MISFIRE_INSTR`,`NEXT_FIRE_TIME`), KEY `IDX_QRTZ_T_NFT_ST_MISFIRE` (`SCHED_NAME`,`MISFIRE_INSTR`,`NEXT_FIRE_TIME`,`TRIGGER_STATE`), KEY `IDX_QRTZ_T_NFT_ST_MISFIRE_GRP` (`SCHED_NAME`,`MISFIRE_INSTR`,`NEXT_FIRE_TIME`,`TRIGGER_GROUP`,`TRIGGER_STATE`), CONSTRAINT `QRTZ_TRIGGERS_ibfk_1` FOREIGN KEY (`SCHED_NAME`, `JOB_NAME`, `JOB_GROUP`) REFERENCES `QRTZ_JOB_DETAILS` (`SCHED_NAME`, `JOB_NAME`, `JOB_GROUP`) ) ENGINE=InnoDB DEFAULT CHARSET=utf8mb4;
注:或者去官網http://www.quartz-scheduler.org/downloads/下載對應的版本下,有以下的目錄:也能夠直接使用該腳本
五、接下來能夠配置數據源,若是項目當中已有對應表數據庫的數據源,則能夠直接使用,若是沒有數據源,則須要用如下代碼建立數據源
package com.yarcl.crm.biz.util;
import com.mchange.v2.c3p0.ComboPooledDataSource; import org.springframework.beans.factory.annotation.Value; import org.springframework.context.annotation.Bean; import org.springframework.context.annotation.Configuration; import javax.sql.DataSource; import java.beans.PropertyVetoException; /** * Created by xiaozhi on 2019/2/25. */ @Configuration public class DataSourceConfig { @Value("${spring.datasource.url}") private String url; @Value("${spring.datasource.password}") private String password; @Value("${spring.datasource.username}") private String username; @Value("${spring.datasource.driverClassName}") private String driverClassName; @Bean("dataSourceBean") public DataSource dataSource() throws PropertyVetoException { ComboPooledDataSource comboPooledDataSource = new ComboPooledDataSource(); comboPooledDataSource.setJdbcUrl(url); comboPooledDataSource.setDriverClass(driverClassName); comboPooledDataSource.setUser(username); comboPooledDataSource.setPassword(password); comboPooledDataSource.setInitialPoolSize(3); comboPooledDataSource.setMaxPoolSize(5); comboPooledDataSource.setMinPoolSize(3); return comboPooledDataSource; } }
注:註解內容請自行參考Springboot註解說明
六、配置Quartz的job配置類,以下代碼:
package com.yarcl.crm.biz.quartz;
import org.quartz.spi.TriggerFiredBundle; import org.springframework.beans.factory.config.AutowireCapableBeanFactory; import org.springframework.context.ApplicationContext; import org.springframework.context.ApplicationContextAware; import org.springframework.scheduling.quartz.SpringBeanJobFactory; import org.springframework.stereotype.Component; /** * Created by xiaozhi on 2019/2/25. */ @Component public class SchedulerQuartzJob extends SpringBeanJobFactory implements ApplicationContextAware { private transient AutowireCapableBeanFactory beanFactory; @Override public void setApplicationContext(final ApplicationContext context) { beanFactory = context.getAutowireCapableBeanFactory(); } @Override protected Object createJobInstance(final TriggerFiredBundle bundle) throws Exception { final Object job = super.createJobInstance(bundle); beanFactory.autowireBean(job); return job; } }
七、配置Quartz的配置類,以下代碼:
package com.yarcl.crm.biz.util;
import com.yarcl.crm.biz.quartz.SchedulerQuartzJob; import org.springframework.beans.factory.annotation.Autowired; import org.springframework.beans.factory.config.PropertiesFactoryBean; import org.springframework.context.annotation.Bean; import org.springframework.context.annotation.Configuration; import org.springframework.core.io.ClassPathResource; import org.springframework.scheduling.concurrent.ThreadPoolTaskExecutor; import org.springframework.scheduling.quartz.SchedulerFactoryBean; import javax.sql.DataSource; import java.io.IOException; import java.util.Properties; /** * Created by xiaozhi on 2019/2/25. */ @Configuration public class SchedulerQuartzConfig { @Autowired private SchedulerQuartzJob schedulerQuartzJob; @Autowired private DataSource dataSourceBean; @Bean(name = "schedulerFactoryBean") public SchedulerFactoryBean schedulerFactoryBean() throws IOException { //獲取配置屬性 PropertiesFactoryBean propertiesFactoryBean = new PropertiesFactoryBean(); propertiesFactoryBean.setLocation(new ClassPathResource("quartz.properties")); //在quartz.properties中的屬性被讀取並注入後再初始化對象 propertiesFactoryBean.afterPropertiesSet(); //建立SchedulerFactoryBean SchedulerFactoryBean factory = new SchedulerFactoryBean(); Properties pro = propertiesFactoryBean.getObject(); factory.setOverwriteExistingJobs(true); factory.setDataSource(dataSourceBean); ThreadPoolTaskExecutor executor = new ThreadPoolTaskExecutor(); executor.setCorePoolSize(10); executor.setMaxPoolSize(20); executor.setQueueCapacity(100); factory.setTaskExecutor(executor); factory.setAutoStartup(true); factory.setQuartzProperties(pro); factory.setJobFactory(schedulerQuartzJob); return factory; } }
八、配置完應有的相關配置內容以後,若是須要執行任務,則任務的處理邏輯必須實現org.quartz.Job接口,代碼以下:
package com.yarcl.crm.biz.quartz;
import com.yarcl.crm.biz.homepage.dao.HomepageDao; import com.yarcl.crm.biz.model.scheduler.SchedulerDo; import com.yarcl.crm.biz.model.scheduler.SchedulerVo; import com.yarcl.crm.biz.service.scheduler.SchedulerService; import lombok.extern.slf4j.Slf4j; import org.quartz.Job; import org.quartz.JobExecutionContext; import org.quartz.JobExecutionException; import org.quartz.JobKey; import org.springframework.beans.factory.annotation.Autowired; /** * Created by xiaozhi on 2019/2/25. */ @Slf4j public class CronJob implements Job { @Autowired private JobService jobService; @Autowired private SchedulerService schedulerService; @Override public void execute(JobExecutionContext jobExecutionContext) throws JobExecutionException { // 獲取job的名稱和group String jobName = jobExecutionContext.getJobDetail().getKey().getName(); String jobGroup = jobExecutionContext.getJobDetail().getKey().getGroup(); Object obj = jobExecutionContext.getMergedJobDataMap().get("executeClass"); Object objFun = jobExecutionContext.getMergedJobDataMap().get("executeFunction"); boolean isTrue = SchedulerDo.class.getSimpleName().equals(obj); if(isTrue) { SchedulerDo sDo = (SchedulerDo)objFun; Long id = sDo.getId();boolean isExist = schedulerService.findExistById(id); if(isExist) { schedulerService.sendMessage(sDo); } else { log.error("The schedule has been deleted when it is cron."); } } // 及時刪除任務 JobKey jobKey = JobKey.jobKey(jobName, jobGroup); if(null != jobKey) { jobService.deleteJob(jobName, jobGroup); } } }
九、添加一個job任務:
public class JobServiceImpl {
// 注入定時任務調度類
@SuppressWarnings("SpringJavaInjectionPointsAutowiringInspection") @Autowired private SchedulerFactoryBean schedulerFactoryBean; /** * 建立一個定時任務 * @param jobName * @param jobGroup */public String addCronJob(String jobName, String jobGroup, SchedulerDo schedulerDo) { try { jobName = jobName+schedulerDo.getRemindDt().getTime()+ UUID.randomUUID(); String dateCron = new SimpleDateFormat("ss mm HH dd MM ? yyyy").format(schedulerDo.getRemindDt()); // 定時調度任務主題-一、構建定時任務調度器 Scheduler scheduler = schedulerFactoryBean.getScheduler(); JobKey jobKey = JobKey.jobKey(jobName, jobGroup); JobDetail jobDetail = scheduler.getJobDetail(jobKey); if (jobDetail == null) { // 定時調度任務主題-二、構建job信息 jobDetail = JobBuilder.newJob(CronJob.class).withIdentity(jobName, jobGroup).build(); //用JopDataMap來傳遞數據 jobDetail.getJobDataMap().put("executeClass", SchedulerDo.class.getSimpleName()); jobDetail.getJobDataMap().put("executeFunction", schedulerDo); //表達式調度構建器(即任務執行的時間) CronScheduleBuilder scheduleBuilder = CronScheduleBuilder.cronSchedule(dateCron); // 定時調度任務主體-三、按新的cronExpression表達式構建一個新的trigger CronTrigger trigger = TriggerBuilder.newTrigger().withIdentity(jobName + "_trigger", jobGroup + "_trigger") .withSchedule(scheduleBuilder).build();
// 開啓調度 scheduler.scheduleJob(jobDetail, trigger); } } catch (Exception e) { e.printStackTrace(); } return jobName; }
}
十、經過調用JobServiceImpl代碼則能夠實現向Quartz任務調度器持久化一個具體時間的調度。當前例子只適用於初學者進行實驗性學習,不具備通用性.