Порядок выполнения и состояние запуска нескольких команд Spring Boot

#java #spring #spring-boot

Вопрос:

У меня есть несколько операций запуска, которые должны выполняться одна за другой. Оба этих бегуна выполняют некоторые сложные операции с базой данных.

 @Slf4j
@Data
@Component
@Order(1)
public class MyFailureHandlerA implements CommandLineRunner {

    @Override
    public void run(String... args) throws Exception {
        some_io_calls_a();
    }

}
 
 @Slf4j
@Data
@Component
@Order(2)
public class MyFailureHandlerB implements CommandLineRunner {

    @Override
    public void run(String... args) throws Exception {
        some_io_calls_b();
    }

}
 

Мне нужно убедиться, что @Order(2) runner запускается только после @Order(1) завершения обработки.

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

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

Или я могу положиться на @dependsOn для завершения задачи? Гарантируется ли, что, используя @DependsOn("MyFailureHandlerA") over MyFailureHandlerB , вы гарантируете, что 1-й бегун завершил все свои операции?

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

 @Slf4j
@Data
@Component
public class MyFailureHandler implements CommandLineRunner {

    @Override
    public void run(String... args) throws Exception {
        some_io_calls_q();
        some_io_calls_b();
    }

}
 

Будет ли это иметь какой-то смысл и обеспечит выполнение операций по порядку одна за другой?

spring-boot-2.3.2

Ответ №1:

 some_io_calls_q();
some_io_calls_b();
 

Если оба ваших метода выполняют синхронизированные задачи, то достаточно использовать порядок.

Ваша команда будет выполнена в соответствии с аннотацией заказа. Вы можете распечатать несколько журналов, чтобы проверить это.

В противном случае для асинхронной задачи этого недостаточно. Вы должны контролировать, когда/как задача будет выполнена…

Наиболее простое решение, как вы описываете, — это вызов обоих методов в одной командной строке на случай, если вы не уверены во внутреннем процессе spring.

@dependsOn: работает только с процессом создания компонента. Это не относительно выполнения команд.