Запуск кода после Spring Загрузка начинается

Я хочу запустить код после того, как приложение spring -boot начнет отслеживать каталог изменений.

Я попытался запустить новый поток, но службы @Autowired не были установлены в этой точке.

Мне удалось найти ApplicationPreparedEvent, который запускается перед аннотациями @Autowired. В идеале я хотел бы, чтобы событие срабатывало, когда приложение готово обрабатывать HTTP-запросы.

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

Ответ 1

Try:

@Configuration
@EnableAutoConfiguration
@ComponentScan
public class Application extends SpringBootServletInitializer {

    @SuppressWarnings("resource")
    public static void main(final String[] args) {
        ConfigurableApplicationContext context = SpringApplication.run(Application.class, args);

        context.getBean(Table.class).fillWithTestdata(); // <-- here
    }
}

Ответ 2

Это так просто, как это:

@EventListener(ApplicationReadyEvent.class)
public void doSomethingAfterStartup() {
    System.out.println("hello world, I have just started up");
}

Протестировано на версии 1.5.1.RELEASE

Ответ 3

Вы пробовали ApplicationReadyEvent?

@Component
public class ApplicationStartup 
implements ApplicationListener<ApplicationReadyEvent> {

  /**
   * This event is executed as late as conceivably possible to indicate that 
   * the application is ready to service requests.
   */
  @Override
  public void onApplicationEvent(final ApplicationReadyEvent event) {

    // here your code ...

    return;
  }
}

Код из: http://blog.netgloo.com/2014/11/13/run-code-at-spring-boot-startup/

Вот что документация упоминает о событиях запуска:

...

События приложения отправляются в следующем порядке по мере запуска вашего приложения:

Приложение ApplicationStartedEvent отправляется в начале запуска, но прежде любая обработка, кроме регистрации слушателей и инициализаторов.

Применяется ApplicationEnvironmentPreparedEvent, когда известна среда, которая будет использоваться в контексте, но до контекста.

Приложение ApplicationPreparedEvent отправляется непосредственно перед запуском обновления, но после загрузки bean.

Приложение ApplicationReadyEvent отправляется после обновления и любые связанные обратные вызовы обрабатываются, чтобы указать, что приложение готово к сервисные запросы.

Приложение ApplicationFailedEvent отправляется, если при запуске есть исключение.

...

Ответ 4

Почему бы просто не создать bean, который запускает ваш монитор при инициализации, например:

@Component
public class Monitor {
    @Autowired private SomeService service

    @PostConstruct
    public void init(){
        // start your monitoring in here
    }
}

метод init не будет вызываться до тех пор, пока не будет выполнено какое-либо аутоописание для bean.

Ответ 5

"Spring Загрузка" - это использовать CommandLineRunner. Просто добавьте beans этого типа, и вам хорошо идти. В Spring 4.1 (Boot 1.2) есть также SmartInitializingBean, который получает обратный вызов после того, как все инициализировано. И есть SmartLifecycle (от Spring 3).

Ответ 6

Вы можете расширить класс с помощью ApplicationRunner, переопределить метод run() и добавить туда код.

import org.springframework.boot.ApplicationRunner;

@Component
public class ServerInitializer implements ApplicationRunner {

    @Override
    public void run(ApplicationArguments applicationArguments) throws Exception {

        //code goes here

    }
}

Ответ 7

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

Однако если ваш сервер находится в состоянии "не готов" до тех пор, пока задача не будет завершена, то лучше реализовать SmartInitializingSingleton поскольку вы получите обратный вызов до того, как ваш порт REST будет открыт, а ваш сервер открыт для бизнеса.

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

Ответ 8

С конфигурацией spring:

@Configuration
public class ProjectConfiguration {
    private static final Logger log = 
   LoggerFactory.getLogger(ProjectConfiguration.class);

   @EventListener(ApplicationReadyEvent.class)
   public void doSomethingAfterStartup() {
    log.info("hello world, I have just started up");
  }
}

Ответ 9

Используйте SmartInitializingSingleton bean в spring > 4.1

@Bean
public SmartInitializingSingleton importProcessor() {
    return () -> {
        doStuff();
    };

}

В качестве альтернативы a CommandLineRunner bean можно реализовать или аннотировать метод bean с помощью @PostConstruct.

Ответ 10

Предоставление примера ответа Дейва Сиера, который работал как шарм:

@Component
public class CommandLineAppStartupRunner implements CommandLineRunner {
    private static final Logger logger = LoggerFactory.getLogger(CommandLineAppStartupRunner.class);

    @Override
    public void run(String...args) throws Exception {
        logger.info("Application started with command-line arguments: {} . \n To kill this application, press Ctrl + C.", Arrays.toString(args));
    }
}

Ответ 11

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

 @Component
public class OnStartServer implements ApplicationListener<ContextRefreshedEvent> {

    @Override
    public void onApplicationEvent(ContextRefreshedEvent arg0) {
                // EXECUTE YOUR CODE HERE 
    }
}

Ответ 12

просто внедрите CommandLineRunner для весенней загрузки приложения. Вам нужно реализовать метод запуска,

public classs SpringBootApplication implements CommandLineRunner{

    @Override
        public void run(String... arg0) throws Exception {
        // write your logic here 

        }
}

Ответ 13

Мне очень нравится предложение для использования в EventListener аннотации по @cahen (fooobar.com/questions/91813/...), так как он очень чистый. К сожалению, я не смог заставить это работать в настройках Spring + Kotlin. Что работает для Kotlin, так это добавление класса в качестве параметра метода:

@EventListener 
fun doSomethingAfterStartup(event: ApplicationReadyEvent) {
    System.out.println("hello world, I have just started up");
}

Ответ 14

Лучший способ выполнить блок кода после запуска приложения Spring Boot - использовать аннотацию PostConstruct. Или вы также можете использовать для этой цели средство запуска командной строки.

1. Использование аннотации PostConstruct

@Configuration
public class InitialDataConfiguration {

    @PostConstruct
    public void postConstruct() {
        System.out.println("Started after Spring boot application !");
    }

}

2. Использование bean-компонента runner командной строки

@Configuration
public class InitialDataConfiguration {

    @Bean
    CommandLineRunner runner() {
        return args -> {
            System.out.println("CommandLineRunner running in the UnsplashApplication class...");
        };
    }
}