Как я могу сделать динамический параметр аннотации @Scheduled?

У меня есть запланированная работа, и я хочу получить фиксированную скорость динамически, но не могу решить, как это сделать.

FixedRate получает значение в миллисекундах, но я хочу указать время в часах. И я также пытался прочитать параметр из файла свойств и умножить его, но у меня не получилось. Как я могу это сделать?

package com.ipera.communicationsuite.scheduleds;

import com.ipera.communicationsuite.models.FreeDbSize;
import com.ipera.communicationsuite.repositories.interfaces.IFreeDbSizeRepository;
import com.ipera.communicationsuite.repositories.interfaces.settings.IPropertiesRepository;
import com.ipera.communicationsuite.utilities.mail.SMTPConnection;
import lombok.AllArgsConstructor;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.context.annotation.PropertySource;
import org.springframework.scheduling.annotation.Scheduled;
import org.springframework.stereotype.Component;

import java.io.File;
import java.util.ArrayList;
import java.util.List;

@Component
@AllArgsConstructor
@PropertySource("classpath:scheduled.properties")
public class KeepAlive {
    private static Logger logger = LoggerFactory.getLogger(KeepAlive.class);

    private IFreeDbSizeRepository freeDbSizeRepository;
    private SMTPConnection smtpConnection;
    private IPropertiesRepository propertiesRepository;



    @Scheduled(fixedRateString ="${keepAlive.timer}")
    public void keepAliveMailSender() {
        StringBuilder content = new StringBuilder();
        ArrayList<File> files = getDrivers();
        List<FreeDbSize> list = freeDbSizeRepository.getFreeDbSize();
        FreeDbSize dbDiskInfo = freeDbSizeRepository.dbDiskSize();
        content.append("DB file size is: ").append(list.get(0).getType().equals("mdf") ? list.get(0).getFileSize() : list.get(1).getFileSize()).append(" MB\n")
                .append("DB log size is: ").append(list.get(0).getType().equals("ldf") ? list.get(0).getFileSize() : list.get(1).getFileSize()).append(" MB\n");
        propertiesRepository.updateByKey("DatabaseSize", list.get(0).getType().equals("mdf") ? list.get(0).getFileSize().toString() : list.get(1).getFileSize().toString());
        propertiesRepository.updateByKey("DatabaseLogSize", list.get(0).getType().equals("ldf") ? list.get(0).getFileSize().toString() : list.get(1).getFileSize().toString());
        propertiesRepository.updateByKey("FreeDiskSpaceForDb", dbDiskInfo.getFreeSpace().toString());
        for (int i = 0; i < files.size(); i++) {
            content.append("Free size for driver ").append(files.get(i)).append(" is ").append(files.get(i).getFreeSpace() / (1024 * 1024)).append(" MB\n");
            propertiesRepository.createIfNotExistOrUpdate(("FreeSpaceInDisk".concat(Character.toString(files.get(i).toString().charAt(0)))), Long.toString(files.get(i).getFreeSpace() / (1024 * 1024)));
        }
        if (dbDiskInfo.getName().equals("-1")) {
            content.append("This application has not permission to run query for calculate free size of disk.");
        } else {
            content.append("Free size of disk which contains Db is: ").append(dbDiskInfo.getFreeSpace());
        }
        smtpConnection.sendMail(content.toString(), "Server Is Up!!!", "[email protected]", "", "", "", "");
        logger.info("KeepAlive has runned.");

    }


    public ArrayList<File> getDrivers() {
        ArrayList<File> list = new ArrayList<>();

        File[] drives = File.listRoots();
        if (drives != null && drives.length > 0) {
            for (File aDrive : drives) {
                list.add(aDrive);
            }

        }
        return list;
    }
}

А также мой файл свойств здесь:

keepAlive.timer=86400000

person f.koglu    schedule 19.06.2020    source источник
comment
stackoverflow.com/a/55736367/5001937   -  person Suraj    schedule 19.06.2020
comment
stackoverflow.com/a/55740402/5001937   -  person Suraj    schedule 19.06.2020
comment
@Suraj, это мне очень помогает. Спасибо чувак!   -  person f.koglu    schedule 22.06.2020


Ответы (1)


Вы можете использовать SpEL в своей аннотации, например:

@Scheduled(fixedRateString ="#{new Long('${keepAlive.timer}') * 1000 * 3600}")

для оценки выражения. Таким образом, keepAlive.timer будет количеством часов.

Но, на мой взгляд, это было бы уродливым решением. Я бы предпочел поместить его в свойства, как у вас сейчас, и просто добавить комментарий, например:

# 24 hours is: 1000 * 3600 * 24  
keepAlive.timer=86400000

Другим способом использования часов может быть использование атрибута cron, который дает вам больше гибкости, но может потребовать некоторого изучения перед использованием:

В вашем коде:

@Scheduled(cron = "${keepAlive.timer}")

и выражение cron в ваших свойствах - например - например:

keepAlive.timer="*/60 00 21 * * ?"

Это будет проходить каждый день в 21.00.

Обратите внимание на это "*/60", оно должно принимать здесь также "0", но в моем случае это не так

person pirho    schedule 19.06.2020