Шесть способов научить вас что-то делать при инициализации SpringBoot!

Spring Boot Java задняя часть

предисловие

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

Итак, вот классический вопрос, который также часто задают интервьюеры: как можно что-то сделать, когда начнется проект Spring Boot?

Существует много методов, ниже приведены некоторые распространенные методы.

1. Мониторинг точки расширения завершения обновления контейнераApplicationListener<ContextRefreshedEvent>

Механизм событий ApplicationContext реализуется шаблоном проектирования наблюдателя, а механизм событий ApplicationContext реализуется через два интерфейса ApplicationEvent и ApplicationListener.

Вот некоторые из встроенных событий Spring:

  1. ContextRefreshedEvent: когда ApplicationContext инициализируется или обновляется, событие публикуется. Это также может произойти с методом refresh() в интерфейсе ConfigurableApplicationContext. Инициализация здесь означает: все компоненты Bean успешно загружены и обнаружены после обработки Bean активированы, все Singleton Bean предварительно созданы, контейнер ApplicationContext готов к использованию.
  2. ContextStartedEvent: это событие публикуется, когда ApplicationContext запускается с помощью метода start() в интерфейсе ConfigurableApplicationContext (субинтерфейс ApplicationContext). Вы можете исследовать свою базу данных или перезапустить любое остановленное приложение после получения этого события.
  3. ContextStoppedEvent: это событие отправляется, когда ApplicationContext останавливается с помощью stop() в интерфейсе ConfigurableApplicationContext. Вы можете выполнить необходимую очистку после получения этого события.
  4. ContextClosedEvent: это событие отправляется, когда ApplicationContext закрывается с помощью метода close() в интерфейсе ConfigurableApplicationContext. Закрытый контекст достигает конца своего жизненного цикла, его нельзя обновить или перезапустить.
  5. RequestHandledEvent: это веб-событие, которое сообщает всем bean-компонентам, что HTTP-запросы были обслужены. Применяется только к веб-приложениям, использующим DispatcherServlet. При использовании Spring в качестве интерфейсного контроллера MVC система автоматически инициирует это событие, когда Spring завершит обработку запроса пользователя.

Что ж, разобравшись с приведенными выше встроенными событиями, мы можем прослушатьContextRefreshedEventВыполните некоторые операции при запуске Spring Boot, код выглядит следующим образом:

@Component
public class TestApplicationListener implements ApplicationListener<ContextRefreshedEvent>{
    @Override
    public void onApplicationEvent(ContextRefreshedEvent contextRefreshedEvent) {
        System.out.println(contextRefreshedEvent);
        System.out.println("TestApplicationListener............................");
    }
}

Расширенный игровой процесс

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

  1. Настройте EmailEvent, код выглядит следующим образом:
public class EmailEvent extends ApplicationEvent{
   private String address;
   private String text;
   public EmailEvent(Object source, String address, String text){
   super(source);
      this.address = address;
      this.text = text;
   }
   public EmailEvent(Object source) {
     super(source);
   }
   //......address和text的setter、getter
}
  1. Пользовательский слушатель, код выглядит следующим образом:
public class EmailNotifier implements ApplicationListener{
   public void onApplicationEvent(ApplicationEvent event) {
     if (event instanceof EmailEvent) {
        EmailEvent emailEvent = (EmailEvent)event;
        System.out.println("邮件地址:" + emailEvent.getAddress());
        System.our.println("邮件内容:" + emailEvent.getText());
     } else {
        System.our.println("容器本身事件:" + event);
     }
   }
}
  1. После отправки письма запустите событие, код выглядит следующим образом:
public class SpringTest {
   public static void main(String args[]){
     ApplicationContext context = new ClassPathXmlApplicationContext("bean.xml");
     //创建一个ApplicationEvent对象
     EmailEvent event = new EmailEvent("hello","abc@163.com","This is a test");
     //主动触发该事件
     context.publishEvent(event);
   }
}

2,SpringBootизCommandLineRunnerинтерфейс

Вызывается при инициализации контейнераCommandLineRunnerсерединаrun()метод, который также может что-то выполнить после запуска контейнера. Этот метод более гибкий, чем ApplicationListener, а именно:

  • разныеCommandLineRunnerможет быть достигнуто путем@Order()Укажите порядок выполнения
  • Может получать параметры, введенные из консоли.

Ниже приведен пользовательский класс реализации, код выглядит следующим образом:

@Component
@Slf4j
public class CustomCommandLineRunner implements CommandLineRunner {

    /**
     * @param args 接收控制台传入的参数
     */
    @Override
    public void run(String... args) throws Exception {
        log.debug("从控制台接收参数>>>>"+ Arrays.asList(args));
    }
}

Чтобы запустить эту банку, команда выглядит следующим образом:

java -jar demo.jar aaa bbb ccc

В приведенной выше команде передаются три параметра:aaa,bbb,cccЭти три параметра будутrun()Метод получен. Как показано ниже:

Анализ исходного кода

Кто читал мою статью, должен знатьCommandLineRunnerКак это исполняется, исходный текст:Серия «Лысая голова», двадцать три изображения позволяют проанализировать процесс запуска Spring Boot из исходного кода~

Запись для Spring Boot для загрузки контекста находится вorg.springframework.context.ConfigurableApplicationContext()В этом методе, как показано ниже:

В вызове CommandLineRunnercallRunners(context, applicationArguments);Выполненный в этом методе исходный код выглядит следующим образом:

3.SpringBootизApplicationRunnerинтерфейс

ApplicationRunnerиCommandLineRunnerВсе они предоставляются Spring Boot, по сравнению сCommandLineRunnerПередаваемые консолью параметры лучше инкапсулировать.Вы можете получить указанные параметры через пары ключ-значение, например--version=2.1.0.

На этом этапе запустите команду jar следующим образом:

java -jar demo.jar --version=2.1.0 aaa bbb ccc

Приведенная выше команда передает четыре параметра, пару ключ-значениеversion=2.1.0, а остальные триaaa,bbb,ccc.

также через@Order()Укажите приоритет следующим образом:

@Component
@Slf4j
public class CustomApplicationRunner implements ApplicationRunner {
    @Override
    public void run(ApplicationArguments args) throws Exception {
        log.debug("控制台接收的参数:{},{},{}",args.getOptionNames(),args.getNonOptionArgs(),args.getSourceArgs());
    }
}

Запустите приведенную выше команду, и результат будет следующим:

Анализ исходного кода

иCommandLineRunnerто же, то жеcallRunners()Выполненный в этом методе исходный код выглядит следующим образом:

4.@PostConstructаннотация

Первые три предназначены для некоторых действий, выполняемых после инициализации контейнера.@PostConstructЭта аннотация дляBeanПосле завершения инициализации выполните некоторые действия, например, зарегистрируйте несколько слушателей...

@PostConstructАннотация обычно размещается на методе компонента.После завершения инициализации компонента будет вызван этот метод.Код выглядит следующим образом:

@Component
@Slf4j
public class SimpleExampleBean {

    @PostConstruct
    public void init(){
        log.debug("Bean初始化完成,调用...........");
    }
}

5. Укажите метод инициализации в аннотации @Bean

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

Создайте новый Бин со следующим кодом:

@Slf4j
public class SimpleExampleBean {

    public void init(){
        log.debug("Bean初始化完成,调用...........");
    }
}

пройти в классе конфигурации@Beanсоздать экземпляр этого компонента, но@BeanсерединаinitMethodЭто свойство должно указывать метод, который должен быть выполнен после инициализации, следующим образом:

@Bean(initMethod = "init")
    public SimpleExampleBean simpleExampleBean(){
        return new SimpleExampleBean();
    }

6.InitializingBeanинтерфейс

InitializingBeanИспользование в основном такое же, как@PostConstructпоследовательный, но соответствующийBeanнеобходимо реализоватьafterPropertiesSetметод, код выглядит следующим образом:

@Slf4j
@Component
public class SimpleExampleBean implements InitializingBean {

    @Override
    public void afterPropertiesSet()  {
        log.debug("Bean初始化完成,调用...........");
    }
}

Суммировать

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