Я планирую как задачу периодически выполнять, скажем, после 1 и в определенное время, например, 10:00.Я использую Java утилита TimerTask как исполняемый в Spring ScheduledExecutorTask.
Я объявляю bean-компоненты как
private void declareAuditBackupBeans(DefaultListableBeanFactory beanFactory, boolean isSuiteServer) throws Exception{
try{
boolean isAuditBackupThreadOn = AuditUtil.isAuditBackupThreadOn();
if(logger.isDebugEnabled()){
logger.debug("AuditBackupThread is : " + isAuditBackupThreadOn);
}
if(!isAuditBackupThreadOn) {
if(logger.isDebugEnabled()){
logger.debug("AuditBackupThread is off. Backup thread won't be started.");
}
return;
}
// set this to false while initializing. just in case it's been left dangling
AuditUtil.setIsBackupCurrentlyRunning(false);
logger.debug("Last successful backup time was : " + AuditUtil.getLastSuccessfulBackupTime());
AuditBackupTimerTask auditBackupTimerTask = new AuditBackupTimerTask();
AuditBackupScheduledTimerTask auditBackupScheduledTimerTask = new AuditBackupScheduledTimerTask();
auditBackupScheduledTimerTask.setDays(getAuditBackupDays());
auditBackupScheduledTimerTask.setAuditBackupDate(getAuditBackupDate());
auditBackupScheduledTimerTask.setRunnable(auditBackupTimerTask);
BeanDefinition beanDefinition = new RootBeanDefinition(AuditBackupScheduledTimerTask.class);
beanFactory.registerBeanDefinition("AuditBackupScheduledTimerTask", beanDefinition);
beanFactory.initializeBean(auditBackupScheduledTimerTask, "AuditBackupScheduledTimerTask");
ScheduledExecutorFactoryBean timerFactoryBean = new ScheduledExecutorFactoryBean();
timerFactoryBean.setDaemon(true);
List<ScheduledExecutorTask> scheduledTimerTasks = new ArrayList<ScheduledExecutorTask>();
scheduledTimerTasks.add(auditBackupScheduledTimerTask);
timerFactoryBean.setScheduledExecutorTasks(scheduledTimerTasks.toArray(new ScheduledExecutorTask[scheduledTimerTasks.size()]));
// Register the bean
beanDefinition = new RootBeanDefinition(ScheduledExecutorFactoryBean.class);
beanFactory.registerBeanDefinition("AuditBackupTimerFactoryBean", beanDefinition);
beanFactory.initializeBean(auditBackupScheduledTimerTask, "AuditBackupTimerFactoryBean");
timerFactoryBean.afterPropertiesSet();
auditBackupScheduledTimerTask.getPeriod();
if (logger.isDebugEnabled()) {
logger.debug("timerFactoryBean: " + timerFactoryBean);
}
}catch(Exception e)
{
logger.error("Error initializing backup thread on server. backup won't be started. " , e);
}
}
Во время выполнения timerFactoryBean.afterPropertiesSet ();stmt - была установлена задержка (AuditBackupScheduledTimerTask.getDelay ()), и она четко отображает время следующего запуска, например, 07 февраля, 10:00, задержка 2019 года на 1 день и время в 10:00, но в это время задача не выполняется
Реализация ScheduledExecutorTask
public class AuditBackupScheduledTimerTask extends ScheduledExecutorTask {
private static final Logger LOG = Logger.getLogger(AuditBackupScheduledTimerTask.class);
private static final int HOURS_IN_DAYS = 24;
private static final int MINS_IN_HOURS = 60;
private static final int SECS_IN_MINS = 60;
private static final int MILLIS_IN_SECS = 1000;
private int days;
private int hour;
private int minute;
public void setAuditBackupDate(String auditBackupDate) throws Exception {
if(LOG.isTraceEnabled()) {
LOG.trace("Parsing the date for audit backup thread : " + auditBackupDate);
}
String[] hhmm = auditBackupDate.split(":");
Boolean isInvalidTime = Boolean.TRUE;
if(hhmm != null && hhmm.length == 2) {
// Parse an hour
String hh = hhmm[0];
if(StringUtils.isNumeric(hh) && Integer.valueOf(hh) >= 0 && Integer.valueOf(hh) <= 23) {
this.hour = new Integer(hh);
// Now parse the time...
String mm = hhmm[1];
if(StringUtils.isNumeric(mm) && Integer.valueOf(mm) >= 0 && Integer.valueOf(mm) <= 59) {
this.minute = new Integer(mm);
isInvalidTime= Boolean.FALSE;
if(LOG.isTraceEnabled()) {
LOG.trace("Hours and Minutes computed as : " + hour + " : " + minute);
}
}
}
}
LOG.debug("Is invalid time: " + isInvalidTime);
if(isInvalidTime) {
LOG.error("Enter the valid time value for configuration key 'auditBackupInTime'. The value should be in 'HH:MM' format and within the valid time range...");
throw new Exception("Incorrect value for property 'Archive start time' is given...");
}
}
public long getDelay () {
long delay = -1;
long lastRun = getLastRun();
Calendar nextRun=Calendar.getInstance();
if(LOG.isDebugEnabled()) {
LOG.debug("Last run information is : " + lastRun + ". In date format : " + new Date(lastRun) + ". [-1] is no last run.");
}
nextRun.set(Calendar.HOUR_OF_DAY, 0);
nextRun.add(Calendar.HOUR_OF_DAY, hour);
nextRun.set(Calendar.MINUTE, 0);
nextRun.add(Calendar.MINUTE, minute);
nextRun.set(Calendar.SECOND,0);
nextRun.set(Calendar.MILLISECOND,0);
if(days > 0){
nextRun.add(Calendar.DAY_OF_MONTH, days);
}else if ( days ==0 && (nextRun.getTimeInMillis() - Calendar.getInstance().getTimeInMillis() < 0)) {
LOG.debug("Configured time for audit backup is elapsed and days is 0. Converting to next day run.");
nextRun.add(Calendar.DAY_OF_MONTH, 1);
}
delay = nextRun.getTimeInMillis() - Calendar.getInstance().getTimeInMillis();
if(LOG.isTraceEnabled()) {
LOG.trace("Delay computed for AuditBackup is : " + delay );
LOG.trace("Time it'll run at is : " + new Date((new Date().getTime() + delay)));
}
return delay;
}
public long getPeriod() {
long period = 0;
long daysToMillis = days * HOURS_IN_DAYS * MINS_IN_HOURS * SECS_IN_MINS * MILLIS_IN_SECS;
long hoursToMillis = hour * MINS_IN_HOURS * SECS_IN_MINS * MILLIS_IN_SECS;
long minsToMillis = minute * MINS_IN_HOURS * SECS_IN_MINS * MILLIS_IN_SECS;
period = daysToMillis + hoursToMillis + minsToMillis;
if(LOG.isTraceEnabled()){
LOG.trace("Period computed for Audit Backup thread is : " + period);
}
return period;
}
}
Реализация TimerTask
public class AuditBackupTimerTask extends TimerTask {
private static final Logger LOG = Logger.getLogger(AuditBackupTimerTask.class);
/**
*
* The run implementation to actually take backup.
* Actually when to run is not controlled here.
*/
@Override
public void run() {
long count = -1;
Date tillDate = null;
Date fromDate = null;
Date scheduledDate = null;
try{
my task
}
private Date getFromDate(Date tillDate) throws DbAccessException {
LOG.trace("Entering getFromDate(" + tillDate + ")...");
DateFormat dateFormat = new SimpleDateFormat(AuditUtil.DATE_FORMAT);
List<AuditEvent> events = AuditEventManager.getInstance().getAuditEventsByNamedQuery("getAuditEventsTillDateInAsc",
0, 1, null, null, dateFormat.format(tillDate), null);
LOG.debug("Returned events: " + events);
Date fromDate = null;
if(events != null && !events.isEmpty()) {
fromDate = events.get(0).getDate();
}
LOG.debug("From date: " + fromDate);
return fromDate;
}
// Take from Configuration
private Date getBackupTillDate() {
LOG.trace("Entering getBackupTillDate()...");
Calendar then = Calendar.getInstance();
then.setTime(new Date());
then.set(Calendar.HOUR_OF_DAY, 23);
then.set(Calendar.MINUTE, 59);
then.set(Calendar.SECOND, 59);
then.set(Calendar.MILLISECOND, 0);
int auditCountToKeep= (int)AuditUtil.getAuditCountToKeep();
LOG.debug("Audit counts to keep from configuration: " + auditCountToKeep);
if(auditCountToKeep > 0)
then.add(Calendar.DAY_OF_YEAR, -Math.abs(auditCountToKeep));
Date d = new Date(then.getTimeInMillis());
LOG.debug("Date till which records will be backed up : " +d);
return d;
}
}
Я не уверен, что ScheduledExecutorTask не выполняет TimerTask или что-то пропущено в моем коде.Во-вторых, я нашел из документации Java.util.TimeTask об его API cancel () -
Отменяет эту задачу таймера.Если задача была запланирована для однократного выполнения и еще не запущена или еще не была запланирована, она никогда не запустится.Если задание было запланировано для повторного выполнения, оно никогда не запустится снова.(Если задание выполняется при этом вызове, задание будет выполнено до конца, но больше никогда не будет выполнено.)
Что означает значение stmt - Если задание было запланированодля однократного выполнения и еще не запущен или еще не был запланирован, он никогда не будет запущен Есть ли вероятность того, что задание таймера не будет выполнено вовремя, и если оно не будет выполнено в данный момент времени, то никогда не выполнится.