Статьи

Запуск кода при запуске Spring Boot

Spring Boot автоматически настраивает нас, но рано или поздно вам придётся выполнять какую-то пользовательскую работу. В этой статье вы узнаете, как подключиться к жизненному циклу загрузки приложения и выполнить код при запуске Spring Boot .

Итак, давайте посмотрим, что предлагает структура.

1. Выполнить метод инициализации бина

Самый простой способ запустить некоторую логику после запуска приложения Spring — это выполнить код как часть выбранного процесса начальной загрузки bean-компонента.

Что ты должен сделать?

Просто создайте класс, отметьте его как компонент Spring и поместите код инициализации приложения в метод с аннотацией @PostConstruct . Теоретически, вы можете использовать конструктор вместо отдельного метода, но это хорошая практика, чтобы отделить конструкцию объекта от его реальной ответственности.

01
02
03
04
05
06
07
08
09
10
11
12
@Component
class AppInitializator {
 
    private static final Logger log = LoggerFactory.getLogger(AppInitializator.class);
 
    @PostConstruct
    private void init() {
        log.info("AppInitializator initialization logic ...");
        // ...
    }
 
}

Если вы используете отложенную инициализацию контекста приложения (например, для ускорения запуска Spring Boot ), компонент с логикой инициализации должен быть исключен из этого механизма. Я описал, как охотно создавать бин с помощью аннотации @Lazy, когда весь контекст Spring использует отложенную загрузку .

Вы также можете создать метод с аннотацией @PostConstruct внутри основного класса приложения Spring Boot. Не забывайте, что основной класс также является компонентом, управляемым фреймворком.

01
02
03
04
05
06
07
08
09
10
11
12
@SpringBootApplication
public class InitDemoApplication {
 
    // ...
 
    @PostConstruct
    private void init() {
        log.info("InitDemoApplication initialization logic ...");
        // ...
    }
 
}

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

2. Spring Boot запускает крючки

Прелесть приложений, созданных с помощью Spring Boot, заключается в том, что единственное, что вам нужно для их запуска, — это среда выполнения Java и интерфейс командной строки. Никаких внешних инструментов или приложений не требуется. Он работает так же, как обычная программа Java SE.

Как и в любой Java-программе, вы запускаете выполнение такого приложения в статическом методе main вашего начального класса приложения. В этот момент вы можете подключиться к процессу инициализации Spring Boot.

2.1. Создание крючка Spring Boot

Начните с изменения кода в вашем основном методе, чтобы извлечь присоединение загрузочных хуков к отдельному методу. Вы должны добавить хуки Spring Boot до запуска приложения.

1
2
3
4
5
6
7
8
9
public static void main(String[] args) {
    SpringApplication application = new SpringApplication(InitDemoApplication.class);
    addInitHooks(application);
    application.run(args);
}
 
static void addInitHooks(SpringApplication application) {
    // TBD …
}

Когда приложение Spring Boot запускается, оно публикует несколько событий на отдельных этапах процесса начальной загрузки. API класса SpringApplication предоставляет метод, который мы можем использовать для добавления прослушивателей для этих событий.

Вот пример, который запускает метод запуска для события, опубликованного до того, как контекст Spring начнет создавать ваши bean-компоненты:

1
2
3
4
5
6
static void addInitHooks(SpringApplication application) {
   application.addListeners((ApplicationListener<ApplicationEnvironmentPreparedEvent>) event -> {
       String version = event.getEnvironment().getProperty("java.runtime.version");
       log.info("Running with Java {}", version);
   });
}

2.2. Типы событий

В зависимости от типа события , объект, который Spring передает слушателю, может дать вам доступ к нескольким полезным операциям. В предыдущем примере мы читали какое-то свойство среды, но мы могли также изменить его при необходимости.

Вот список возможных событий, отсортированных по порядку публикации событий при загрузке Spring Boot при запуске:

  • ApplicationStartingEvent
  • ApplicationEnvironmentPreparedEvent
  • ApplicationContextInitializedEvent
  • ApplicationPreparedEvent
  • ApplicationStartedEvent
  • ApplicationReadyEvent

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

По моему опыту, наиболее важным событием является ApplicationEnvironmentPreparedEvent . На момент запуска Spring Boot компоненты еще не созданы, но вы можете получить доступ ко всей конфигурации приложения. Обычно это лучший момент для запуска собственного кода запуска.

3. Запустите код при запуске без встроенного Tomcat

Несмотря на то, что разработчики Spring Boot создали среду с учетом создания толстых JAR-файлов, некоторые разработчики по-прежнему разворачивают приложения Spring Boot в обычных контейнерах сервлетов, таких как Tomcat. Если это так, решение из предыдущего параграфа не будет работать без дополнительного шага.

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

Вы можете легко использовать метод addInitHooks (), который мы создали в основном классе приложения.

1
2
3
4
5
6
7
8
9
public class InitDemoWarInitializer extends SpringBootServletInitializer {
 
    @Override
    protected SpringApplicationBuilder configure(SpringApplicationBuilder builder) {
        InitDemoApplication.addInitHooks(builder.application());
        return builder.sources(InitDemoApplication.class);
    }
 
}

Вывод

Короче говоря, есть два основных варианта запуска кода при запуске Spring Boot. Самый простой из них предназначен для инициализации конкретного компонента. Для более глобальных случаев платформа имеет специальное решение для подключения к своему жизненному циклу с использованием прослушивателей событий. Мы узнали, как реализовать и настроить таких слушателей.

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

Смотреть оригинальную статью здесь: Запуск кода при запуске Spring Boot

Мнения, высказанные участниками Java Code Geeks, являются их собственными.