Open1

Spring Boot (2.4.1) "How-to" Guidesを読んだメモ

daisuzzdaisuzz

Spring Boot Application

Failure Analyzer

  • FailureAnalyzer
    • 起動時の例外を傍受して、可読性のあるメッセージに変換するクラス
    • application-context関連の例外やJSR-303 validationなどのためのanalyzer

Auto Configuration

  • ConditionEvaluationReport
    • 実行時にSpring Bootがどのような機能を有効にして、どのような機能を有効にしていないかを確認することができる
  • AutoConfiguration関連のソースコードを読むコツ
    • *AutoConfigurationという名前のクラスを探す
    • @Conditional*というアノテーションが付与されたクラスやメソッドを探す
      • どのような条件のときにどのような機能が有効になるか確認できる
      • -debugを付与してアプリを起動することでAutoConfigurationのログをみることができる
      • Spring Boot Actuatorを使うことで/conditionsにアクセスすることで起動中のログをみることができる
    • @ConfigurationPropertiesが付与されたクラスを探す
      • *Propertiesという名前のクラスが多い
      • 利用可能な外部設定オプションを確認できる
    • Binder#bind()を使っている箇所を探す
      • Environmentクラスから明示的に設定値を取得する(relaxed bind)
    • Environtmentへ直接バインドする@Valueを探す
    • @ConditionalOnExpressionを探す
      • SpEL式によって機能を有効にしたり無効にする
      • SpEL式は通常は、Environtmentクラスから解決されたプレースホルダーを使って評価される

Customize Environtment or Application Context

  • ApplicationListeners, ApplicationContextInitializers
    • contextやenvironmentをカスタマイズするためのクラス
    • META-INF/spring.factoryからこのようなクラスをロードする
  • Spring Applicationは特別なApplicationEventsをいくつかリスナーに送り、その後ApplicationContextによってパブリッシュされるいくつかのイベントのためのリスナーを登録する
  • EnvironmentPostProcessorを使って、アプリケーションコンテキストを更新する前に、Environmentをカスタマイズすることができる
    • EnvironmentPostProcessorの実装クラスはMETA-INF/spring.factoriesに追加して登録する
      • org.springframework.boot.env.EnvironmentPostProcessor=com.example.YourEnvironmentPostProcessor
    • 任意のファイルを読み込んでEnvironmentに追加することができる
      public class EnvironmentPostProcessorExample implements EnvironmentPostProcessor {
      
        private final YamlPropertySourceLoader loader = new YamlPropertySourceLoader();
      
        @Override
        public void postProcessEnvironment(ConfigurableEnvironment environment, SpringApplication application) {
            Resource path = new ClassPathResource("com/example/myapp/config.yml");
            PropertySource<?> propertySource = loadYaml(path);
            environment.getPropertySources().addLast(propertySource);
        }
      
        private PropertySource<?> loadYaml(Resource path) {
            if (!path.exists()) {
                throw new IllegalArgumentException("Resource " + path + " does not exist");
            }
            try {
                return this.loader.load("custom-resource", path).get(0);
            }
            catch (IOException ex) {
                throw new IllegalStateException("Failed to load yaml configuration from " + path, ex);
            }
        }
      }
      
    • Enrironmentには、Spring Bootがデフォルトでロードするプロパティソースが全て用意されている
      • Environmentからファイルの場所を取得することができる
    • @SpringBootApplicationを使ったアプリケーション内で@PropertySourceを使ってEnvironmentにプロパティソースを追加ことは非推奨
      • アプリケーションコンテキストが更新されるまでEnvirontmentに追加されないため
      • アプリケーションコンテキストの更新前に読み込まれるlogging.*spring.main.*のようなプロパティを設定する用途では読み込まれるタイミングが遅すぎる

参考

https://docs.spring.io/spring-boot/docs/current/reference/html/howto.html#howto-spring-boot-application