Spring Boot には、CommandLineRunner と ApplicationRunner という 2 つのインターフェイスがあり、アプリケーションの起動時に特別な処理を行うために使用されます。 SpringApplication で使用されます run() メソッドは、実行が完了する前に実行されます。前の章で紹介した Spring の ApplicationListener インターフェースのカスタム リスナーとサーブレットの ServletContextListener リスナーと比較します。 両方を使用する利点は、アプリケーションの起動パラメータを簡単に使用でき、さまざまなパラメータに応じてさまざまな初期化操作を実行できることです。
CommandLineRunner インターフェイスと ApplicationRunner インターフェイスを実装します。通常、アプリケーションの起動前に次のような特別なコードを実行するために使用されます。
システムでよく使用されるデータをメモリにロードします
アプリケーションの前回の実行時間ガベージデータのクリーニングを実行しました。
システム起動成功後の通知の送信など。
CommandLineRunner インターフェイスを実装し、アプリケーションの起動時にシステムをロードしました。一般的に使用される構成データを次の図に示します。データベースからデータをメモリにロードします。今後データを使用する場合は、getSysConfigList メソッドを呼び出すだけでよく、毎回データベースにデータをロードする必要はありません。システム リソースを節約し、データの読み込み時間を短縮します。
CommandLineRunner: パラメーターは文字列配列です。
@Slf4j @Component public class CommandLineStartupRunner implements CommandLineRunner { @Override public void run(String... args){ log.info("CommandLineRunner传入参数:{}", Arrays.toString(args)); } }
ApplicationRunner:パラメータは ApplicationArguments に入れて getOptionNames()、getOptionValues()、getSourceArgs() でパラメータを取得します
@Slf4j @Component public class AppStartupRunner implements ApplicationRunner { @Override public void run(ApplicationArguments args) { log.info("ApplicationRunner参数名称: {}", args.getOptionNames()); log.info("ApplicationRunner参数值: {}", args.getOptionValues("age")); log.info("ApplicationRunner参数: {}", Arrays.toString(args.getSourceArgs())); } }
このメソッドは実行順序を指定できますので注意してください最初の 2 つの Bean は CommandLineRunner、最後の Bean は ApplicationRunner です。
@Configuration public class BeanRunner { @Bean @Order(1) public CommandLineRunner runner1(){ return new CommandLineRunner() { @Override public void run(String... args){ System.out.println("BeanCommandLineRunner run1()" + Arrays.toString(args)); } }; } @Bean @Order(2) public CommandLineRunner runner2(){ return new CommandLineRunner() { @Override public void run(String... args){ System.out.println("BeanCommandLineRunner run2()" + Arrays.toString(args)); } }; } @Bean @Order(3) public ApplicationRunner runner3(){ return new ApplicationRunner() { @Override public void run(ApplicationArguments args){ System.out.println("BeanApplicationRunner run3()" + Arrays.toString(args.getSourceArgs())); } }; } }
@Order
IDEA Springboot 起動構成に次のパラメータを追加し、アプリケーションを保存して起動します
テスト出力結果:
c.z.boot.launch.config.AppStartupRunner : ApplicationRunner パラメータ名: [name, age]
c.z.boot .launch.config.AppStartupRunner : ApplicationRunner パラメーター値: [18]
c.z.boot.launch.config.AppStartupRunner : ApplicationRunner パラメーター: [--name=zimug, --age=18]BeanApplicationRunner run3 ()[-- name=zimug, --age=18]
c.z.b.l.config.CommandLineStartupRunner : CommandLineRunner 受信パラメーター: [--name=zimug, --age=18]
BeanCommandLineRunner run1() [--name =zimug, --age=18]
e=18]
BeanCommandLineRunner run2()[--name=zimug, --age=18]
著者は何度もテストしました テストの結果、この優先順位は常にこのようであることがわかりましたが、これが標準であるかどうかを判断することは現時点では不可能です
ApplicationRunnerの実行CommandLineRunner よりも優先度が高い
#Bean 形式で実行される Runner の優先度は、Component アノテーションよりも低く、Runner インターフェースを実装します。 #Order アノテーションは、同じ CommandLineRunner または ApplicationRunner の実行順序のみを保証できますが、クラス間で順序を保証することはできません
4. 概要
これは、作成者が実際に遭遇した実際の問題であり、CommandLineRunner の複数の実装を定義しました。奇妙な問題が発生します。
CommandLineRunner の複数の実装を定義すると、そのうちの 1 つまたは複数が実行されません。分析: 次のコードは、プロジェクトの開始後に SpringBootApplication が実行するコードで、コード内のトラバーサルを通じて CommandLineRunner または ApplicationRunner が開始されることがわかります。つまり、次の CommandLineRunner は、同期的に実行される前の CommandLineRunner の実行が完了した後にのみ実行されます。 以上がSpringboot アプリケーション サービスの起動イベントの監視を実装する方法の詳細内容です。詳細については、PHP 中国語 Web サイトの他の関連記事を参照してください。private void callRunners(ApplicationContext context, ApplicationArguments args) {
List<Object> runners = new ArrayList<>();
runners.addAll(context.getBeansOfType(ApplicationRunner.class).values());
runners.addAll(context.getBeansOfType(CommandLineRunner.class).values());
AnnotationAwareOrderComparator.sort(runners);
for (Object runner : new LinkedHashSet<>(runners)) {
if (runner instanceof ApplicationRunner) {
callRunner((ApplicationRunner) runner, args);
}
if (runner instanceof CommandLineRunner) {
callRunner((CommandLineRunner) runner, args);
}
}
}