サンプルコードで身につける: 自動構成は候補を条件でふるいにかける
解説で学んだ概念を、5つの具体例で確認します。素朴な例から実務寄りの例へと進みます。
1素の Java で条件つき登録を真似る
候補の一覧を回し、があるか、同じ型の がまだ無いかを調べて登録するだけのプログラムです。 は使っていません。自分で List の Bean を先に入れておくと、候補のほうは登録されずに引っ込みます。がやっていることの骨組みはこの形です。
2imports ファイルの実物
の中の spring/org.springframework.boot.autoconfigure.AutoConfiguration.imports の全文を2つ並べました(# の行は見出しとして足したもの)。中身は構成クラスの名前が1行に1つあるだけです。4.1.1 ではこのファイルが JAR ごとにあり、 だけのでは6つの JAR に合計 30 行でした。
# spring-boot-webmvc-4.1.1.jar(6行)org.springframework.boot.webmvc.autoconfigure.DispatcherServletAutoConfigurationorg.springframework.boot.webmvc.autoconfigure.WebMvcAutoConfigurationorg.springframework.boot.webmvc.autoconfigure.WebMvcObservationAutoConfigurationorg.springframework.boot.webmvc.autoconfigure.actuate.endpoint.web.WebMvcHealthEndpointExtensionAutoConfigurationorg.springframework.boot.webmvc.autoconfigure.actuate.web.mappings.WebMvcMappingsAutoConfigurationorg.springframework.boot.webmvc.autoconfigure.error.ErrorMvcAutoConfiguration# spring-boot-jackson-4.1.1.jar(1行)org.springframework.boot.jackson.autoconfigure.JacksonAutoConfiguration
3条件評価レポートを読む
を付けて起動すると出るレポートの抜粋です。Positive matches には通った条件とその理由が、Negative matches には通らなかった理由が出ます。JacksonAutoConfiguration は JsonMapper のクラスが見つかったので通り、CBOR や XML 用の入れ子の構成は必要なクラスが無いので外れています。この最小アプリでは Positive が 52 件、Negative が 39 件でした。
============================CONDITIONS EVALUATION REPORT============================Positive matches:-----------------...JacksonAutoConfiguration matched:- @ConditionalOnClass found required class 'tools.jackson.databind.json.JsonMapper' (OnClassCondition)JacksonAutoConfiguration#jacksonJsonMapper matched:- @ConditionalOnMissingBean (types: tools.jackson.databind.json.JsonMapper; SearchStrategy: all) did not find any beans (OnBeanCondition)...Negative matches:-----------------...JacksonAutoConfiguration.CborConfiguration:Did not match:- @ConditionalOnClass did not find required class 'tools.jackson.dataformat.cbor.CBORMapper' (OnClassCondition)JacksonAutoConfiguration.XmlConfiguration:Did not match:- @ConditionalOnClass did not find required class 'tools.jackson.dataformat.xml.XmlMapper' (OnClassCondition)...
4自分で Bean を定義する前と後の diff
JsonMapper の Bean を自分で定義する前(<)と後(>)で、レポートを比べた結果です。jacksonJsonMapper が Positive 側から消えて Negative 側に移り、理由が did not find any beans から found beans ... myJsonMapper に変わっています。件数の差も 52→51、39→40 のこの1件だけでした。リファレンスはこの性質を、自動構成は non-invasive(押しつけない)と表現しています。
70,72d69< JacksonAutoConfiguration#jacksonJsonMapper matched:< - @ConditionalOnMissingBean (types: tools.jackson.databind.json.JsonMapper; SearchStrategy: all) did not find any beans (OnBeanCondition)<85c82< - @ConditionalOnBean (types: tools.jackson.databind.json.JsonMapper; SearchStrategy: all) found bean 'jacksonJsonMapper' (OnBeanCondition)---> - @ConditionalOnBean (types: tools.jackson.databind.json.JsonMapper; SearchStrategy: all) found bean 'myJsonMapper' (OnBeanCondition)201a199,202>> JacksonAutoConfiguration#jacksonJsonMapper:> Did not match:> - @ConditionalOnMissingBean (types: tools.jackson.databind.json.JsonMapper; SearchStrategy: all) found beans of type 'tools.jackson.databind.json.JsonMapper' myJsonMapper (OnBeanCondition)
5依存を足すと候補そのものが増える
web だけのプロジェクトと、data-jpa と h2 を足したプロジェクトで、imports ファイルの行数を JAR ごとに数えた表です。DataSourceAutoConfiguration は spring-boot-jdbc の JAR の imports に載っているので、web だけのほうでは --debug の出力にその名前が1回も出ません。条件で外れたのではなく、候補に入っていないということです。
imports を持つ JAR | web だけ | web + data-jpa + h2------------------------------+----------+--------------------spring-boot-autoconfigure | 12 | 12spring-boot-webmvc | 6 | 6spring-boot-tomcat | 5 | 5spring-boot-servlet | 5 | 5spring-boot-jackson | 1 | 1spring-boot-http-converter | 1 | 1spring-boot-jdbc | - | 9spring-boot-transaction | - | 3spring-boot-hibernate | - | 2spring-boot-data-commons | - | 2spring-boot-data-jpa | - | 1spring-boot-persistence | - | 1spring-boot-h2console | - | 1------------------------------+----------+--------------------imports の合計行数 | 30 | 49クラスパスの JAR の数 | 39 | 74レポートの Positive matches | 52 | 89レポートの Negative matches | 39 | 64