あべぶろ

気になった技術の備忘録を残します。

【Spring Boot】@AutoConfigureを理解する。

概要

Spring Bootには、Bean定義を自動で行ってくれるAutoConfigureという仕組みがある。
今まで何となく使っていたので、ここで理解を深めたい。
こちらの記事が非常に良く纏まっているので、参考にさせて頂く。*1

AutoConfigure

16. Auto-configuration
Spring Boot auto-configuration attempts to automatically configure your Spring application based on the jar dependencies that you have added.

  • 追加したjarの依存関係に基づいて、Springアプリケーションを自動で設定してくれる。 *2
  • Spring FrameworkではxmlでBeanの定義をしていたが、Spring Bootでは不要でる。

自動設定をするには、対象クラスに@SpringBootApplicationか@EnableAutoConfigurationを付与する必要がある。

サンプル

@SpringBootApplication
public class SampleApplication {
	/* 以下省略 */
}
  • 自動設定を有効にするために@SpringBootApplicationを付与している。

@SpringBootApplicationを付与するだけで、DIコンテナに様々なBeanを登録してくれる。
では、Beanはどのように登録されているのだろうか?

@EnableAutoConfiguration

上述で述べた@EnableAutoConfigurationから紐解いてみる。
ちなみに、@SpringBootApplicationは内部で@EnableAutoConfigurationを使用している。
他にもアノテーションを利用しているが今回は省略する。

@Import(EnableAutoConfigurationImportSelector.class)
public @interface EnableAutoConfiguration {
	/* 以下省略 */
}
  • @Importで他のコンフィギュレーションクラスをインポートしている。
  • クラスを直接指定せずに、EnableAutoConfigurationImportSelectorを指定している。
  • EnableAutoConfigurationImportSelectorはspring-boot-autoconfigure.jar/META-INF/spring.factoriesに列挙されているコンフィギュレーションクラスを取得する。

spring.factoriesはこんな感じ。

# Auto Configure
org.springframework.boot.autoconfigure.EnableAutoConfiguration=\
org.springframework.boot.autoconfigure.admin.SpringApplicationAdminJmxAutoConfiguration,\
org.springframework.boot.autoconfigure.aop.AopAutoConfiguration,\
org.springframework.boot.autoconfigure.amqp.RabbitAutoConfiguration,\
org.springframework.boot.autoconfigure.batch.BatchAutoConfiguration,\
org.springframework.boot.autoconfigure.cache.CacheAutoConfiguration,\
org.springframework.boot.autoconfigure.cassandra.CassandraAutoConfiguration,\
org.springframework.boot.autoconfigure.cloud.CloudAutoConfiguration,\
/* 以下省略 */

これを見ると末尾にAutoConfigurationとつけるようになっている。自作ライブラリ用のコンフィギュレーションクラスを作成する際は、この命名規則に準ずるのが良さそう。

CassandraAutoConfigurationを覗いてみる。

/* 一部抜粋 */
@Configuration // (1)
@ConditionalOnClass({ Cluster.class }) // (2)
@EnableConfigurationProperties(CassandraProperties.class) // (3)
public class CassandraAutoConfiguration {

	private final CassandraProperties properties;

	private final List<ClusterBuilderCustomizer> builderCustomizers;

	public CassandraAutoConfiguration(CassandraProperties properties,
			ObjectProvider<List<ClusterBuilderCustomizer>> builderCustomizers) {
		this.properties = properties;
		this.builderCustomizers = builderCustomizers.getIfAvailable();
	}

	@Bean
	@ConditionalOnMissingBean // (4)
	public Cluster cluster() {
		CassandraProperties properties = this.properties;
		Cluster.Builder builder = Cluster.builder()
				.withClusterName(properties.getClusterName())
				.withPort(properties.getPort());
		if (properties.getUsername() != null) {
			builder.withCredentials(properties.getUsername(), properties.getPassword());
		}
		/* 省略 */
		customize(builder);
		return builder.build();
	}
}
項番 説明
(1) コンフィギュレーションクラスであることを定義している。Beanの登録をする事が可能となる。
(2) 指定したクラスがクラスパス上に存在した場合に適用される。
(3) 利用するプロパティクラスを定義している。そしてコンストラクタインジェクションでDIされている??ここは理解不足。
(4) BeanがDIコンテナに登録されていない場合に適用される。
  • Clusterクラスはcassandra-driver-coreライブラリに含まれている。なので、デフォルトでは含まれていない。エラーにならないのは謎である。
  • Beanを登録するコンフィギュレーションクラスと設定値を保持するプロパティクラスは切分けされている。
  • 自分は今まで同じクラス内に書いていたので、このように分けた方が良さそうだ。

このコンフィギュレーションクラスが正常に動作すれば、ClusterクラスのBeanがDIコンテナに登録されるはずである。今回はそこまで追わないが、今後もう少し調べてみたい。

まとめ

AutoConfigureの仕組みを理解する事が出来た。
この仕組みを使う事で、Spring上でOSSを使いやすくしている。
また、自作ライブラリにも取入れて簡単に扱いやすくしてみたい。