Выполнение кода после загрузки начинается весна
Я хочу, чтобы запустить код после spring-boot приложение начинает отслеживать каталог для изменений.
Я попытался запустить новый поток, но @Autowired службы не были установлены в этот момент.
мне удалось найти ApplicationPreparedEvent, который срабатывает перед тем, как @Autowired аннотации расположены. В идеале я хотел бы, чтобы событие срабатывало после того, как приложение готово обрабатывать http-запросы.
есть лучше использовать, или лучше запуск кода после того, как приложение будет жить в spring-boot?
10 ответов:
попробуй:
@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 } }
это так просто:
@EventListener(ApplicationReadyEvent.class) public void doSomethingAfterStartup() { System.out.println("hello world, I have just started up"); }протестировано на версии
1.5.1.RELEASE
почему бы просто не создать боб, который запускает ваш монитор при инициализации, что-то вроде:
@Component public class Monitor { @Autowired private SomeService service @PostConstruct public void init(){ // start your monitoring in here } }the
initметод не будет вызван до тех пор, пока не будет выполнена какая-либо автопроводка для Боба.
вы пробовали 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 отправляется непосредственно перед началом обновления,но после загрузки определений компонентов.
ApplicationReadyEvent отправляется после обновления и все связанные обратные вызовы были обработаны, чтобы указать приложение готово к работе сервисные запросы.
ApplicationFailedEvent отправляется, если есть исключение при запуске.
...
способ "весенней загрузки" заключается в использовании
CommandLineRunner. Просто добавьте бобы этого типа, и вы хорошо идти. Весной 4.1 (Boot 1.2) также естьSmartInitializingBeanкоторый получает обратный вызов после того, как все было инициализировано. И естьSmartLifecycle(С весны 3).
вы можете расширить класс с помощью
ApplicationRunner, переопределитьrun()метод и добавить туда код.import org.springframework.boot.ApplicationRunner; @Component public class ServerInitializer implements ApplicationRunner { @Override public void run(ApplicationArguments applicationArguments) throws Exception { //code goes here } }
С весны конфигурация :
@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"); } }
ApplicationReadyEventдействительно полезно только в том случае, если задача, которую вы хотите выполнить, не является требованием для правильной работы сервера. Хорошим примером является запуск асинхронной задачи для отслеживания изменений.Если, однако, ваш сервер находится в состоянии "не готов", пока задача не будет завершена, то лучше реализовать
SmartInitializingSingletonпотому что вы получите обратный вызов до ваш порт REST был открыт, и ваш сервер открыт для бизнеса.не поддавайтесь искушению использовать
@PostConstructдля задач, которые должны произойти только один раз. Вы получите грубый сюрприз, когда заметите, что он вызывается несколько раз...
использовать
SmartInitializingSingletonБоб весной > 4.1@Bean public SmartInitializingSingleton importProcessor() { return () -> { doStuff(); }; }как вариант
CommandLineRunnerbean можно реализовать или аннотировать метод bean с помощью@PostConstruct.
предоставление примера для ответа Дейва Сиера, который работал как шарм:
@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)); } }
Comments