Spring @Scheduled: как определить, был ли метод вызван как задание?

Spring имеет аннотацию @Scheduled, которая делает вызов метода запланированным заданием.

Поддерживается ли способ узнать в методе, был ли он вызван этим планированием или непосредственно из другого кода?

Под supported я подразумеваю, что это не может быть какой-то хак, например проверка стека вызовов, или использование какого-то побочного эффекта, такого как HTTP-запрос где-то в контексте.


person Ondra Žižka    schedule 19.03.2021    source источник
comment
Нет, это невозможно   -  person Simon Martinelli    schedule 19.03.2021
comment
Дополнительная информация представлена ​​здесь stackoverflow.com/questions/21892072/   -  person aksappy    schedule 19.03.2021


Ответы (2)


Как уже отмечалось, это невозможно. Просто краткая мысль о вашем дизайне: если вы хотите знать, когда он вызывается из планировщика, извлеките запланированный метод и вызовите свой метод с добавленным параметром, например fromScheduler.

Что-то вроде этого:

@Scheduled
public void callAnotherMethod() {
   methodYouWantToCall(true);
}

public void methodYouWantToCall(boolean fromScheduler) {
   if (fromScheduler) {
      log.debug("called from scheduler");
   } else {
      log.debug("non from scheduler");
   }
}

Это сложно, но это позволит избежать просмотра трассировки стека. Лично я не вижу причин, по которым вы не могли бы просто использовать трассировку стека.

boolean scheduled = Arrays.stream(Thread.currentThread().getStackTrace())
    .anyMatch(stackTraceElement -> stackTraceElement.getClassName().contains(
        ScheduledMethodRunnable.class.getName()));
person lane.maxwell    schedule 19.03.2021
comment
Спасибо. Это то, что у нас есть, и так как у нас много работы, я хотел избавиться от этих методов... - person Ondra Žižka; 08.04.2021

Вы пробовали использовать аспекты? Что-то вроде этого:

@Aspect
@Component
public class LogInterceptor {

    private static final Logger log = LoggerFactory.getLogger(LogInterceptor.class);

    @Before("execution(public * my.package.name.schedulers..*.*(..))")
    public void logBeforeAllSchedulers(JoinPoint joinPoint) {
        String className = joinPoint.getSignature().getDeclaringType().getSimpleName();
        String methodName = joinPoint.getSignature().getName();
        Object[] args = joinPoint.getArgs();

        log.debug("Executing: [{}]", "class: " + className + ", method: " + methodName + ", arguments: " + Arrays.toString(args));
    }
}
person DaviM    schedule 22.03.2021