web-dev-qa-db-ja.com

Spring Bootの起動後にコードを実行する

私のspring-bootアプリがディレクトリの変更を監視し始めた後にコードを実行したいです。

新しいスレッドを実行しようとしましたが、その時点で@Autowiredサービスは設定されていません。

@Autowiredアノテーションが設定される前に起動するApplicationPreparedEventを見つけることができました。理想的には、アプリケーションがHTTPリクエストを処理する準備が整ったら、イベントを発生させます。

もっと良いイベントを使うべきでしょうか、それともアプリケーションが起動した後にコードを実行するためのもっと良い方法がありますかspring-boot

140
stewsters

試してください:

@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
    }
}
90
Anton Bessonov

それはこれと同じくらい簡単です:

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

バージョン1.5.1.RELEASEでテスト済み

208
cahen

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が送信されます。

...

84
raspacorp

初期化時にモニタを起動するBeanを作成しないでください。

@Component
public class Monitor {
    @Autowired private SomeService service

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

initメソッドは、Beanに対して自動配線が行われるまで呼び出されません。

77
cjstehno

"Spring Boot"の方法はCommandLineRunnerを使うことです。その種類の豆を加えるだけで、あなたは行ってもいいです。 Spring 4.1(Boot 1.2)では、すべてが初期化された後にコールバックを取得するSmartInitializingBeanもあります。そして、(Spring 3から)SmartLifecycleがあります。

58
Dave Syer

ApplicationRunner を使用してクラスを拡張し、run()メソッドをオーバーライドしてそこにコードを追加することができます。

import org.springframework.boot.ApplicationRunner;

@Component
public class ServerInitializer implements ApplicationRunner {

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

        //code goes here

    }
}
33
Gimhani

ApplicationReadyEventは、実行したいタスクが正しいサーバー操作の要件ではない場合にのみ実際に役立ちます。変更を監視する非同期タスクを開始するのは良い例です。

しかし、タスクが完了するまであなたのサーバが '準備ができていない'状態にある場合は、コールバック before your RESTポートが開かれサーバが開いているのでSmartInitializingSingletonを実装するのが良いでしょう。営業中。

今までに一度だけ起こるべきタスクのために@PostConstructを使いたくないでしょう。あなたはそれが複数回呼び出されていることに気づくときあなたは失礼な驚きを得るでしょう...

19
Andy Brown

ばねの構成を使って:

@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");
  }
}
19
freemanpolys

春> 4.1にSmartInitializingSingleton Beanを使用する

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

}

代わりにCommandLineRunner Beanを実装するか、または@PostConstructを使ってBeanメソッドに注釈を付けることができます。

11
Jeff

Dave Syerの回答の例を示します。これは魅力のように機能しました。

@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));
    }
}
4
Paulo Pedroso

これを試してみると、アプリケーションコンテキストが完全に起動したときにコードが実行されます。

 @Component
public class OnStartServer implements ApplicationListener<ContextRefreshedEvent> {

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

spring Bootアプリケーション用のCommandLineRunnerを実装するだけです。 runメソッドを実装する必要があります

public classs SpringBootApplication implements CommandLineRunner{

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

        }
}
2
prasad kp

Spring Bootアプリケーションの起動後にコードブロックを実行する最良の方法は、PostConstructアノテーションを使用することです。または、同じためにコマンドラインランナーを使用することもできます。

1。PostConstructアノテーションを使用

@Configuration
public class InitialDataConfiguration {

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

}

2。コマンドラインランナーBeanの使用

@Configuration
public class InitialDataConfiguration {

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

それはあるので、@ cahen( https://stackoverflow.com/a/44923402/9122660 )によるEventListenerアノテーションの使用に関する提案が本当に好きです。非常にきれいな。あいにく私はこれをSpring + Kotlinの設定で動かすことができませんでした。 Kotlinでうまくいくのは、クラスをメソッドパラメータとして追加することです。

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