SHOEISHA iD

※旧SEメンバーシップ会員の方は、同じ登録情報(メールアドレス&パスワード)でログインいただけます

CodeZine編集部では、現場で活躍するデベロッパーをスターにするためのカンファレンス「Developers Summit」や、エンジニアの生きざまをブーストするためのイベント「Developers Boost」など、さまざまなカンファレンスを企画・運営しています。

Spring Bootで作るマイクロサービス

Spring Bootの自動設定の仕組みを理解する

Spring Bootで作るマイクロサービス 第8回


  • X ポスト
  • このエントリーをはてなブックマークに追加

自動設定クラスの構造

 Gsonの自動設定を行っているGsonAutoConfigurationクラスのコードを抜粋したのがリスト4です。

@Configuration(proxyBeanMethods = false) // (1) 設定ファイルの指定
@ConditionalOnClass(Gson.class) // (2) 設定条件の指定
@EnableConfigurationProperties(GsonProperties.class) // (3) 設定ファイルとの連携
public class GsonAutoConfiguration {
    // 省略
    @Bean
    @ConditionalOnMissingBean // (4) Bean登録がなければ作成する
    public Gson gson(GsonBuilder gsonBuilder) {
        return gsonBuilder.create();
    }
    // 省略
}

 (1)が設定ファイルを示す指定です。proxyBeanMethodsを指定していますが、この指定はCGLIBというJavaコード生成ライブラリを使ったオブジェクトのサブクラスを作らない設定です。

 (2)では、@ConditionalOnClassというアノテーションがあります。このアノテーションは指定したクラスが存在するときだけ有効になるといった意味になります。従って、この場合、Gson.classというクラス定義がどこにもなければ、この設定クラスは動作しません。

 そして、(3)ではapplication.properties等の設定ファイルで指定可能な項目を定義するためのクラスを指定しています。

 (4)の@ConditionalOnMissingBeanは、どこにも作成するオブジェクトがBean登録されていない場合に、作成するという指定です。従って、自分で設定クラスを作成し、そこで該当のオブジェクトを作成している場合には、このコードは実行されません。

 多くの場合には、クラスでのアノテーションで@ConditionalOnClassを指定し、@Bean登録では@ConditionalOnMissingBeanを指定するのが通常の流れになります。こういった構造で自動設定クラスはできているので、このクラスの意味がわかれば、他のクラスも同様に理解できるはずです。

 また、自分で自動設定クラスを作成した場合には、そのクラスを含むjarファイル内のMETA-INF/spring.factoriesにリスト4のように記述すれば登録可能です。

自動設定クラスに使われる主なアノテーション

 先ほど、紹介した@ConditionalOnClassや、@ConditionalOnMissingBean以外にも、主に表1のアノテーションが存在します。

 これらのアノテーションは自動設定クラスを自作する場合以外には必要ありませんが、おおよそのどういったことができるのかを知っていると、動作の仕組みを想像しやすくなるはずです。

表1:Spring Bootの自動設定クラスを作成するときに利用する主なアノテーション
アノテーション 説明
@ConditionalOnClass 指定するクラスが存在する場合に実行される
@ConditionalOnMissingClass 指定するクラスが存在しない場合に実行される
@ConditionalOnBean 指定するオブジェクトがBean登録されている場合に実行される
@ConditionalOnMissingBean 指定するオブジェクトがBean登録されていない場合に実行される
@ConditionalOnProperty 指定したプロパティがルールに一致する場合に実行される
@ConditionalOnResource 指定したリソースがルールに一致する場合に実行される

 これらの詳しい使い方やその他のアノテーションは、Spring Boot Referenceに記述がありますので、詳しく知りたい方は参照してください。

 このようなアノテーションを使い、それぞれのライブラリやフレームワーク等の設定を組み合わせに応じて設定していくことが可能になっています。

自動設定クラスの利用可否を個別にカスタマイズする

 Spring Bootの既存で設定されている自動設定クラスを部分的に除外したい、もしくは、指定したものだけ使いたいといった場合があります。

 そういったケースはあまり多くはないかもしれませんが、どうしても自動で作成されるオブジェクトはなくしたい場合や、暗黙の動作をなるべくなくしたい場合になどに有効です。

Spring Bootの設定ファイル(@SpringBootConfiguration)

 通常のSpring Bootのアプリケーションでは、@SpringBootApplicationアノテーションが指定しています。

 このアノテーションには、リスト5のように@SpringBootConfigurationと@EnableAutoConfigurationが指定されています。

[リスト5]@SpringBootConfigurationアノテーション内のコード
@SpringBootConfiguration // (1) @Configuration同等
@EnableAutoConfiguration // (2) 自動設定クラスを使う

 (2)の指定を行ったままでは、すべての自動設定クラスが利用されてしまうので、@SpringBootApplicationが使えません。

 また、(1)は@Configurtionと同様ですが、慣例的にSpring Bootのメインアプリケーションには@SpringBootConfigurationを使います。

自動設定クラスから指定したクラスのみ除外する場合

 自動設定クラスから一部のクラスのみ除外したい場合にはリスト6のように@EnableAutoConfigurationのexcludeもしくはexcludeNameを使用します。

[リスト6]指定した自動設定クラスのみを除外する場合のSpringApplicationの記述例
@SpringBootConfiguration
@EnableAutoConfiguration(exclude = { GsonAutoConfiguration.class })
// 以下のようにも記述可能
@EnableAutoConfiguration(excludeName = { "org.springframework.boot.autoconfigure.gson.GsonAutoConfiguration" } )

設定済みの自動設定クラスを使わないで、個別に設定クラスを指定する場合

 既存で設定されている自動設定クラスを使わないで、個別に設定クラスを使う場合には、リスト7のように@ImportAutoConfigurationを利用します。

[リスト7]指定した自動設定クラスのみを有効にする場合のSpringApplicationの記述例
@SpringBootConfiguration
@ImportAutoConfiguration({GsonAutoConfiguration.class})

自動設定や登録されているBeanを確認する

 自分で設定を作成し、カスタマイズしたものが実際どのように機能しているかを確認する場合には、起動時にDEBUG=1としてリスト8のように起動すると情報を取得することができます。

[リスト8]DEBUGオプションをつけて自動設定の状態を表示し、実行する例
$DEBUG=1 ./gradlew bootRun

============================
CONDITIONS EVALUATION REPORT
============================
Positive matches:
-----------------
 : (省略)
GsonAutoConfiguration matched:
      - @ConditionalOnClass found required class 'com.google.gson.Gson' (OnClassCondition)
 :  (省略)
Negative matches:
-----------------
:   (省略)
   ActiveMQAutoConfiguration:
      Did not match:
         - @ConditionalOnClass did not find required class 'javax.jms.ConnectionFactory' (OnClassCondition)
:   (省略)

 Positive matchesには、適用されたクラスとその条件が表示され、Negative matchesには適用されなかったクラスとその理由となる条件が表示されます。

 また、実際にBean登録されているオブジェクトを参照するには、リスト9のコードで参照可能です。

[リスト9]Bean登録されているオブジェクト名の一覧を取得する(src/main/java/com/coltware/springboot/main/config/SampleApplication.javaの抜粋)
: (省略)
public void start(ApplicationContext context){
    : (省略)
    String beans[] = context.getBeanDefinitionNames();
    for(int i = 0; i < beans.length; i++){
        log.info("bean name : {}",beans[i]);
    }
}
// 以下実行結果
2019-11-21 15:46:19.851  INFO 71764 --- [           main] c.c.springboot.main.SampleApplication    : bean name : org.springframework.context.annotation.internalConfigurationAnnotationProcessor
2019-11-21 15:46:19.851  INFO 71764 --- [           main] c.c.springboot.main.SampleApplication    : bean name : org.springframework.context.annotation.internalAutowiredAnnotationProcessor
2019-11-21 15:46:19.851  INFO 71764 --- [           main] c.c.springboot.main.SampleApplication    : bean name : org.springframework.context.annotation.internalCommonAnnotationProcessor
2019-11-21 15:46:19.851  INFO 71764 --- [           main] c.c.springboot.main.SampleApplication    : bean name : org.springframework.context.event.internalEventListenerProcessor
2019-11-21 15:46:19.851  INFO 71764 --- [           main] c.c.springboot.main.SampleApplication    : bean name : org.springframework.context.event.internalEventListenerFactory
2019-11-21 15:46:19.851  INFO 71764 --- [           main] c.c.springboot.main.SampleApplication    : bean name : sampleApplication

最後に

 Spring Bootの最も大きな特徴であると同時に暗黙的に使用していることが多いため、最もわかりにくい部分の1つが自動設定(Autoconfigure)です。

 今回の自動設定の仕組みを知る過程で、Spring BootがWebアプリケーションの範囲だけではなく、さまざまなライブラリを考慮して作られていることがわかるはずです。Spring Bootに慣れてくるとさまざまなカスタマイズをしたり、Spring Bootを使ってアプリケーションを作ったりするケースも出てくると思います。

 筆者もこの仕組みを知ったことで、実装側における多少の動作の違いを設定ファイル等で分けるのではなく、自動設定用ライブラリを作成し、それを切り替えることで動作を分けるようにしています。例えば、テスト向けの外部モックが含まれるような場合の設定と、本番用の設定といった形に分けます。

 今回紹介したSpring Bootの自動設定の仕組みを理解していれば、Spring Bootを使う上でわからないことがあっても、自分で調べることができるのではないかと思います。

 また、Spring Bootには、本連載で紹介しきれなかった機能もありますが、これまでの内容を参考にSpring Bootの新たな側面を発見していただければ幸いです。

参考資料

 

本連載の書籍が発売されました!

Javaによる高速Webアプリケーション開発のためのSpring Boot入門

Amazon(POD) Amazon(電子書籍) その他

Javaによる高速Webアプリケーション開発のためのSpring Boot入門

著者:WINGSプロジェクト 小林昌弘
発売日:2020年5月31日(水)
価格(POD):2,200円(税込)
価格(電書):1,760円(税込)

この記事は参考になりましたか?

  • X ポスト
  • このエントリーをはてなブックマークに追加
Spring Bootで作るマイクロサービス連載記事一覧

もっと読む

この記事の著者

WINGSプロジェクト 小林 昌弘(コバヤシ マサヒロ)

WINGSプロジェクトについて>有限会社 WINGSプロジェクトが運営する、テクニカル執筆コミュニティ(代表 山田祥寛...

※プロフィールは、執筆時点、または直近の記事の寄稿時点での内容です

山田 祥寛(ヤマダ ヨシヒロ)

静岡県榛原町生まれ。一橋大学経済学部卒業後、NECにてシステム企画業務に携わるが、2003年4月に念願かなってフリーライターに転身。Microsoft MVP for Visual Studio and Development Technologies。執筆コミュニティ「WINGSプロジェクト」代表。主な著書に「独習シリーズ(Java・C#・Python・PHP・Ruby・JSP&サーブレットなど)」「速習シリーズ(ASP.NET Core・Vue.js・React・TypeScript・ECMAScript、Laravelなど)」「改訂3版JavaScript本格入門」「これからはじめるReact実践入門」「はじめてのAndroidアプリ開発 Kotlin編 」他、著書多数

※プロフィールは、執筆時点、または直近の記事の寄稿時点での内容です

この記事は参考になりましたか?

この記事をシェア

  • X ポスト
  • このエントリーをはてなブックマークに追加
CodeZine(コードジン)
https://codezine.jp/article/detail/11897 2020/06/01 19:05

おすすめ

アクセスランキング

アクセスランキング

イベント

CodeZine編集部では、現場で活躍するデベロッパーをスターにするためのカンファレンス「Developers Summit」や、エンジニアの生きざまをブーストするためのイベント「Developers Boost」など、さまざまなカンファレンスを企画・運営しています。

新規会員登録無料のご案内

  • ・全ての過去記事が閲覧できます
  • ・会員限定メルマガを受信できます

メールバックナンバー

アクセスランキング

アクセスランキング