私のspring-bootアプリがディレクトリの変更を監視し始めた後にコードを実行したいです。
新しいスレッドを実行しようとしましたが、その時点で@Autowired
サービスは設定されていません。
@Autowired
アノテーションが設定される前に起動するApplicationPreparedEvent
を見つけることができました。理想的には、アプリケーションがHTTPリクエストを処理する準備が整ったら、イベントを発生させます。
もっと良いイベントを使うべきでしょうか、それともアプリケーションが起動した後にコードを実行するためのもっと良い方法がありますかspring-boot。
試してください:
@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
でテスト済み
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が送信されます。
...
初期化時にモニタを起動するBeanを作成しないでください。
@Component
public class Monitor {
@Autowired private SomeService service
@PostConstruct
public void init(){
// start your monitoring in here
}
}
init
メソッドは、Beanに対して自動配線が行われるまで呼び出されません。
"Spring Boot"の方法はCommandLineRunner
を使うことです。その種類の豆を加えるだけで、あなたは行ってもいいです。 Spring 4.1(Boot 1.2)では、すべてが初期化された後にコールバックを取得するSmartInitializingBean
もあります。そして、(Spring 3から)SmartLifecycle
があります。
ApplicationRunner
を使用してクラスを拡張し、run()
メソッドをオーバーライドしてそこにコードを追加することができます。
import org.springframework.boot.ApplicationRunner;
@Component
public class ServerInitializer implements ApplicationRunner {
@Override
public void run(ApplicationArguments applicationArguments) throws Exception {
//code goes here
}
}
ApplicationReadyEvent
は、実行したいタスクが正しいサーバー操作の要件ではない場合にのみ実際に役立ちます。変更を監視する非同期タスクを開始するのは良い例です。
しかし、タスクが完了するまであなたのサーバが '準備ができていない'状態にある場合は、コールバック before your RESTポートが開かれサーバが開いているのでSmartInitializingSingleton
を実装するのが良いでしょう。営業中。
今までに一度だけ起こるべきタスクのために@PostConstruct
を使いたくないでしょう。あなたはそれが複数回呼び出されていることに気づくときあなたは失礼な驚きを得るでしょう...
ばねの構成を使って:
@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");
}
}
春> 4.1にSmartInitializingSingleton
Beanを使用する
@Bean
public SmartInitializingSingleton importProcessor() {
return () -> {
doStuff();
};
}
代わりにCommandLineRunner
Beanを実装するか、または@PostConstruct
を使ってBeanメソッドに注釈を付けることができます。
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));
}
}
これを試してみると、アプリケーションコンテキストが完全に起動したときにコードが実行されます。
@Component
public class OnStartServer implements ApplicationListener<ContextRefreshedEvent> {
@Override
public void onApplicationEvent(ContextRefreshedEvent arg0) {
// EXECUTE YOUR CODE HERE
}
}
spring Bootアプリケーション用のCommandLineRunnerを実装するだけです。 runメソッドを実装する必要があります
public classs SpringBootApplication implements CommandLineRunner{
@Override
public void run(String... arg0) throws Exception {
// write your logic here
}
}
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...");
};
}
}
それはあるので、@ 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");
}