一.首先明白Spring下Quartz的使用:
需要用到3个类:由上而下依次引用
第一个类
注入了triggers的调度工厂Bean类
org.springframework.scheduling.quartz.SchedulerFactoryBean
第二个类
注入了jobDetail和startDelay及repeatInterval的简单触发器Bean类:
org.springframework.scheduling.quartz.SimpleTriggerBean
或者注入了jobDetail和cronExpression的动态触发器:
org.springframework.scheduling.quartz.CronTriggerBean
第三个类
注入了targetObject和targetMethod的任务详情工厂Bean类:
org.springframework.scheduling.quartz.MethodInvokingJobDetailFactoryBean
二.第一种是静态的定时任务
主要是
SimpleTriggerBean
的属性repatInterval的赋值:设置间隔周期的毫秒值
1.书写详细的配置文件:
<!--备份数据库配置 -->
<bean id="simpleTrigger_dbbak" class="org.springframework.scheduling.quartz.SimpleTriggerBean">
<property name="jobDetail" ref="dbbakjob" />
<property name="startDelay" value="0" /><!-- 调度工厂实例化后,经过0秒开始执行调度 -->
<property name="repeatInterval" value="36000000" /><!-- 毫秒级计算,900000==每15分钟调度一次 -->
</bean>
<bean id="dbbakjob"
class="org.springframework.scheduling.quartz.MethodInvokingJobDetailFactoryBean">
<property name="targetObject">
<ref bean="metaDataDbBackupService" />
</property>
<property name="targetMethod" value="backupDb" />
<property name="concurrent" value="true" /><!-- 作业不并发调度 -->
</bean>
2.service的Bean注入
<!-- 元数据的备份操作 -->
<bean id="metaDataDbBackupService"
class="com.gilight.dep.metadata.service.impl.MetaDataDbBackupServiceImpl">
<property name="cacheManager" ref="cacheManager"></property>
<property name="metaDataBaseRepository" ref="metaDataBaseRepository"></property>
<property name="metaModelQueryService" ref="metaModelQueryService"></property>
</bean>
3.书写对应的业务类
- MetaDataDbBackupServiceImpl 业务类需要实现
- IMetaDataDbBackupService 接口
public class MetaDataDbBackupServiceImpl extends BasicServiceImpl<String> implements
IMetaDataDbBackupService {
private static final Logger logger = Logger.getLogger(MetaDataDbBackupServiceImpl.class);
private IMetaDataBaseRepository metaDataBaseRepository = null;
private IMetaModelQueryService metaModelQueryService = null;
public IMetaModelQueryService getMetaModelQueryService() {
return metaModelQueryService;
}
public void setMetaModelQueryService(
IMetaModelQueryService metaModelQueryService) {
this.metaModelQueryService = metaModelQueryService;
}
public IMetaDataBaseRepository getMetaDataBaseRepository() {
return metaDataBaseRepository;
}
public void setMetaDataBaseRepository(
IMetaDataBaseRepository metaDataBaseRepository) {
this.metaDataBaseRepository = metaDataBaseRepository;
}
@Override
public void backupDb() throws Exception {
String path=(String) CustomizedPropertySpringConfigurer.getContextProperty("jdbc.backuppath");
int radomInt = new Random().nextInt(999999999);
String userName = (String) CustomizedPropertySpringConfigurer.getContextProperty("jdbc.username");
String password=(String) CustomizedPropertySpringConfigurer.getContextProperty("jdbc.password");
String sid=(String) CustomizedPropertySpringConfigurer.getContextProperty("jdbc.sid");
MdDbBackup mdDbBackup = new MdDbBackup();
mdDbBackup.setId(UUIDGenerator.getUUID());
mdDbBackup.setStartTime(MetaDateUtils.getDefaultUpdateDate());
mdDbBackup.setFileName(radomInt+".dmp");
mdDbBackup.setResult(DbBakResultStatus.RUNTIME+"");
this.getMetaDataBaseRepository().create(mdDbBackup);
//String pathfile=path+"/"+radomInt;
if (OracleDatabaseBackup.exportDatabaseTool(userName,password,sid,path,radomInt+"")){
logger.warn("数据库备份成功");
mdDbBackup.setResult(DbBakResultStatus.SUCCEED+"");
}else {
logger.error("数据库备份失败");
mdDbBackup.setResult(DbBakResultStatus.FAILED+"");
}
mdDbBackup.setEndTime(MetaDateUtils.getDefaultUpdateDate());
this.getMetaDataBaseRepository().update(mdDbBackup);
}
}
三、第二种是动态的定时任务
主要是
CronTriggerBean
的cronExpression属性的cron表达式的赋值;
1. 书写详细的配置文件:
<!--动态触发器 org.springframework.scheduling.quartz.CronTriggerBean -->
<bean id="cronTrigger" class="org.springframework.scheduling.quartz.CronTriggerBean">
<property name="jobDetail" ref="dbBackUpJob" />
<property name="cronExpression" value="0 0 12 * * ?" /><!--每天中午12点触发-->
</bean>
<bean id="simpleTrigger_dbbak" class="org.springframework.scheduling.quartz.SimpleTriggerBean">
<property name="jobDetail" ref="dbbakjob" />
<property name="startDelay" value="0" /><!-- 调度工厂实例化后,经过0秒开始执行调度 -->
<property name="repeatInterval" value="36000000" /><!-- 毫秒级计算,900000==每15分钟调度一次 -->
</bean>
2. 其他配置,业务类和上面第一种一样
四、动态地从前台获得cronExpression并存储在数据库;
需要解决的问题是,自定义一个触发器CustomCronTrigger
- 需要继承CronTriggerBean;
-
当数据库中的cronExpression改变时,停掉并删除原来的定时任务,
重新添加一个改变后的定时任务,(这个cronExpression一般是周期性的定时任务); - 要注入一个初始化定时任务的业务;
1. 书写详细的配置文件:
<!-- 我的调度工厂 -->
<bean id="mySchedulerFactoryBean"
class="org.springframework.scheduling.quartz.SchedulerFactoryBean"
lazy-init="false">
<property name="triggers">
<list>
<ref local="customCronTrigger" />
</list>
</property>
</bean>
<!-- 自定义触发器 -->
<bean id="customCronTrigger" class="com.gilight.dep.metadata.service.impl.CustomCronTrigger">
<property name="jobDetail" ref="myJobDetail" />
<property name="initBackupTimeService" ref="initBackupTimeService"></property>
</bean>
<!-- 动态备份系统jobDetail -->
<bean id="myJobDetail"
class="org.springframework.scheduling.quartz.MethodInvokingJobDetailFactoryBean">
<property name="targetObject">
<ref bean="systemBackupService" />
</property>
<property name="targetMethod" value="backupSystem" />
<property name="concurrent" value="false" /><!-- 作业不并发调度 -->
</bean>
2.书写Service的配置文件:
<!-- 系统备份业务 -->
<bean id="systemBackupService" class="com.gilight.dep.metadata.service.impl.SystemBackupServiceImpl">
<property name="systemBackupRepository" ref="systemBackupRepository"></property>
<property name="metaDataDbBackupService" ref="metaDataDbBackupService"></property>
<property name="mySchedulerFactoryBean" ref="mySchedulerFactoryBean"></property>
<property name="customCronTrigger" ref="customCronTrigger"></property>
<property name="myJobDetail" ref="myJobDetail"></property>
</bean>
<!--初始化系统备份时间业务 -->
<bean id="initBackupTimeService" class="com.gilight.dep.metadata.service.impl.InitBackupTimeServiceImpl">
<property name="systemBackupRepository" ref="systemBackupRepository"></property>
</bean>
3.对应业务类的关系图
4.书写对应的业务类:
(1).初始化系统备份的更新时间实现类
/**
* 初始化系统备份的更新时间实现类
*
*/
public class InitBackupTimeServiceImpl implements IInitBackupTimeService{
private static final Logger logger = Logger.getLogger(InitBackupTimeServiceImpl.class);
//注入属性
private ISystemBackupRepository systemBackupRepository = null;
public ISystemBackupRepository getSystemBackupRepository() {
return systemBackupRepository;
}
public void setSystemBackupRepository(ISystemBackupRepository systemBackupRepository) {
this.systemBackupRepository = systemBackupRepository;
}
/**
* 获取CronExpression
*/
@Override
public String getCronExpressionFromDB() throws ServiceException{
logger.info("-------从数据库初始化最新的系统备份时间---------------");
try {
List<MdSystemBackup> list = systemBackupRepository.getAll();
if(list != null && list.size()>0){
//返回表达式
return list.get(0).getCronExpression();
}
return "";
} catch (RepositoryException e) {
e.printStackTrace();
throw new ServiceException("从数据库获取最新系统备份时间异常");
}
}
}
(2).自定义触发器:
获取初始化系统备份的更新时间
在将cronExpression设置到CronTriggerBean中;
/**
* 自定义触发器
* 初始化系统的备份时间
*/
public class CustomCronTrigger extends CronTriggerBean implements Serializable{
//注入初始化时间业务
private IInitBackupTimeService initBackupTimeService;
public IInitBackupTimeService getInitBackupTimeService() {
return initBackupTimeService;
}
public void setInitBackupTimeService(IInitBackupTimeService initBackupTimeService) throws ServiceException{
this.initBackupTimeService = initBackupTimeService;
//获取表达式
String cronExpression = initBackupTimeService.getCronExpressionFromDB();
if(cronExpression!=null && !cronExpression.equals("")){
try{//设置表达式
setCronExpression(cronExpression);
}catch(Exception e){
e.printStackTrace();
throw new ServiceException("自定义触发器的初始化系统的备份时间异常");
}
}
}
}
(3).这个类很重要
1.首先注入5个属性;
private ISystemBackupRepository systemBackupRepository;//系统备份仓储层
private IMetaDataDbBackupService metaDataDbBackupService;//系统备份业务接口
private Scheduler mySchedulerFactoryBean;//注入调度工厂,类型Scheduler
private CustomCronTrigger customCronTrigger;//注入自定义触发器
private JobDetail myJobDetail;//注入任务详情
2.备份任务的方法backupSystem()
3.保存更新时间的方法
//当前台页面修改了备份时间会访问这个方法
saveBackupTime(String backupTime,String period);
//从触发器中获得原来执行时间和页面传来最新时间对比,如果不同,执行
changeJobDetail(backupTime);
4.改变定时任务的方法changeJobDetail(String backupTime)
//是这个类Scheduler
mySchedulerFactoryBean;
//注入调度工厂,类型Scheduler
//改变定时任务:删除原来的任务
mySchedulerFactoryBean.deleteJob("myJobDetail", Scheduler.DEFAULT_GROUP);
//添加新任务:其中返回值的Date是触发器下次执行的时间
Date scheduleJob = mySchedulerFactoryBean.scheduleJob(myJobDetail, customCronTrigger);
//开启新任务:mySchedulerFactoryBean.start();
/**
* 系统备份实现类
* 修改定时任务
*/
public class SystemBackupServiceImpl extends BasicServiceImpl implements ISystemBackupService{
private static final Logger logger = Logger.getLogger(SystemBackupServiceImpl.class);
@Override
public IResponse getByScope(IContext paramIContext) throws ServiceException {
return null;
}
@Override
public IModel initModel(IContext paramIContext) throws Exception {
return null;
}
@Override
public Class getModelClass() {
return null;
}
//==============注入属性===============//
private ISystemBackupRepository systemBackupRepository;//系统备份仓储层
private IMetaDataDbBackupService metaDataDbBackupService;//系统备份业务接口
private Scheduler mySchedulerFactoryBean;//注入调度工厂,类型Scheduler
private CustomCronTrigger customCronTrigger;//注入自定义触发器
private JobDetail myJobDetail;//注入任务详情
public ISystemBackupRepository getSystemBackupRepository() {
return systemBackupRepository;
}
public void setSystemBackupRepository(ISystemBackupRepository systemBackupRepository) {
this.systemBackupRepository = systemBackupRepository;
}
public JobDetail getMyJobDetail() {
return myJobDetail;
}
public void setMyJobDetail(JobDetail myJobDetail) {
this.myJobDetail = myJobDetail;
}
public IMetaDataDbBackupService getMetaDataDbBackupService() {
return metaDataDbBackupService;
}
public void setMetaDataDbBackupService(IMetaDataDbBackupService metaDataDbBackupService) {
this.metaDataDbBackupService = metaDataDbBackupService;
}
public CustomCronTrigger getCustomCronTrigger() {
return customCronTrigger;
}
public void setCustomCronTrigger(CustomCronTrigger customCronTrigger) {
this.customCronTrigger = customCronTrigger;
}
public Scheduler getMySchedulerFactoryBean() {
return mySchedulerFactoryBean;
}
public void setMySchedulerFactoryBean(Scheduler mySchedulerFactoryBean) {
this.mySchedulerFactoryBean = mySchedulerFactoryBean;
}
/**
* 改变定时任务
* @param backupTime
* @throws ParseException
* @throws SchedulerException
*/
public void changeJobDetail(String backupTime) throws ParseException, SchedulerException {
logger.info("-------改变定时任务-------");
logger.info("原触发器: "+customCronTrigger.toString());
//更新触发器执行的时间
customCronTrigger.setCronExpression(backupTime);
//关闭原任务
boolean deleteJob = mySchedulerFactoryBean.deleteJob("myJobDetail", Scheduler.DEFAULT_GROUP);
if(deleteJob){
//添加新任务;返回值Date是触发器下次执行的时间
Date scheduleJob = mySchedulerFactoryBean.scheduleJob(myJobDetail, customCronTrigger);
logger.info("新触发器下次执行的时间: "+scheduleJob);
logger.info("新触发器: "+customCronTrigger.toString());
//开启新任务
mySchedulerFactoryBean.start();
}
}
@Override
public void saveBackupTime(String backupTime,String period) throws ServiceException {
logger.info("----------开始保存系统更新时间--------------");
try {
MdSystemBackup mdSystemBackup = new MdSystemBackup();
String saveTime = MetaDateUtils.getDefaultUpdateDate();//当前时间
String status = "1";//初始状态
String userid = null;//用户id
mdSystemBackup.setId(UUIDGenerator.getUUID());
mdSystemBackup.setCronExpression(backupTime);
mdSystemBackup.setPeriod(period);
mdSystemBackup.setSaveTime(saveTime);
mdSystemBackup.setStatus(status);
mdSystemBackup.setUserid(userid);
//先清空表数据
this.getSystemBackupRepository().empty();
//再保存新数据
this.getSystemBackupRepository().create(mdSystemBackup);
} catch (RepositoryException e1) {
e1.printStackTrace();
}
logger.info("----------保存系统更新时间完毕--------------");
try {// 原触发器的时间
String cronExpression = customCronTrigger.getCronExpression();
if (!cronExpression.equals(backupTime)) {
// 前台时间与原触发器时间不同时,执行改变任务
changeJobDetail(backupTime);
}
} catch (ParseException e) {
e.printStackTrace();
} catch (SchedulerException e) {
e.printStackTrace();
}
}
/**
* 备份job操作
*/
public void backupSystem() {
logger.info("--------开始执行备份任务--------");
//调用开始备份的方法
metaDataDbBackupService.startDbbak();
logger.info("--------备份任务执行完毕--------");
}
}
2017/10/25/18:14 –By HDNew
版权声明:本文为new_seas原创文章,遵循 CC 4.0 BY-SA 版权协议,转载请附上原文出处链接和本声明。