Springの@Configurationアノテーション

Springの@Configurationアノテーションは、Springのコアフレームワークの一部です。Spring Configurationアノテーションは、クラスに@Bean定義メソッドがあることを示します。そのため、Springコンテナはクラスを処理し、アプリケーションで使用するためのSpring Beansを生成することができます。

Spring @Configuration

Springの@Configurationアノテーションを使用すると、依存性の注入にアノテーションを使用できます。Spring Configurationクラスの作成方法を理解しましょう。簡単なJavaビーンクラスを作成しましょう。

package com.journaldev.spring;

public class MyBean {

	public MyBean() {
		System.out.println("MyBean instance created");
	}
	
}

Springのフレームワーククラスを使用する前に、Mavenプロジェクトに依存関係を追加する必要があります。

<dependency>
		<groupId>org.springframework</groupId>
		<artifactId>spring-context</artifactId>
		<version>5.0.6.RELEASE</version>
</dependency>

さて、Spring Configurationクラスを作成しましょう。

package com.journaldev.spring;

import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;

@Configuration
public class MyConfiguration {

    @Bean
    public MyBean myBean() {
		return new MyBean();
	}
	
}

簡単なクラスを書いて、単純なSpringの設定クラスを構成しましょう。

package com.journaldev.spring;

import org.springframework.context.annotation.AnnotationConfigApplicationContext;

public class MySpringApp {

	public static void main(String[] args) {
		AnnotationConfigApplicationContext ctx = new AnnotationConfigApplicationContext();
		ctx.register(MyConfiguration.class);
		ctx.refresh();

		// MyBean mb1 = ctx.getBean(MyBean.class);

		// MyBean mb2 = ctx.getBean(MyBean.class);

		ctx.close();
	}

}

上記のアプリケーションを実行すると、次のような出力が生成されます。

May 23, 2018 12:34:54 PM org.springframework.context.support.AbstractApplicationContext prepareRefresh
INFO: Refreshing org.springframework.context.annotation.AnnotationConfigApplicationContext@ff5b51f: startup date [Wed May 23 12:34:54 IST 2018]; root of context hierarchy
MyBean instance created
May 23, 2018 12:34:54 PM org.springframework.context.support.AbstractApplicationContext doClose
INFO: Closing org.springframework.context.annotation.AnnotationConfigApplicationContext@ff5b51f: startup date [Wed May 23 12:34:54 IST 2018]; root of context hierarchy

注意してください。Springは、私たちがリクエストする前にすべてのビーンをコンテキストにロードします。これは、すべてのビーンが適切に構成され、アプリケーションが何かが間違っている場合には素早く失敗するようにするためです。また、ctx.refresh()を呼び出さないと、コンテキストから任意のビーンを取得しようとしたときに次のエラーが発生します。

Exception in thread "main" java.lang.IllegalStateException: org.springframework.context.annotation.AnnotationConfigApplicationContext@f0f2775 has not been refreshed yet
	at org.springframework.context.support.AbstractApplicationContext.assertBeanFactoryActive(AbstractApplicationContext.java:1076)
	at org.springframework.context.support.AbstractApplicationContext.getBean(AbstractApplicationContext.java:1106)
	at com.journaldev.spring.MySpringApp.main(MySpringApp.java:11)

コメントを外すと、MyBeanインスタンスを取得している文で、MyBeanのコンストラクタが呼び出されていないことに気付くでしょう。これはspring beansのデフォルトのスコープがSingletonであるためです。これは@Scopeアノテーションを使用して変更できます。

もし@Configurationアノテーションをコメントアウトした場合はどうなりますか?

MyConfigurationクラスから@Configurationアノテーションを削除した場合、それでも期待どおりに動作し、Springビーンがシングルトンクラスとして登録および取得されます。ただし、この場合、myBean()メソッドを呼び出すと、通常のJavaメソッド呼び出しになり、MyBeanの新しいインスタンスが取得され、シングルトンではなくなります。このポイントを証明するために、MyBeanインスタンスを使用する別のビーンを定義しましょう。

package com.journaldev.spring;

public class MyBeanConsumer {

	public MyBeanConsumer(MyBean myBean) {
		System.out.println("MyBeanConsumer created");
		System.out.println("myBean hashcode = "+myBean.hashCode());
	}

}

更新されたSpring構成クラスは次のとおりです:

package com.journaldev.spring;

import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;

//@Configuration
public class MyConfiguration {

	@Bean
    public MyBean myBean() {
		return new MyBean();
	}
	
	@Bean
    public MyBeanConsumer myBeanConsumer() {
		return new MyBeanConsumer(myBean());
	}
}

今、MySpringApp クラスを実行すると、以下の出力が生成されます。

MyBean instance created
MyBean instance created
MyBeanConsumer created
myBean hashcode = 1647766367

したがって、MyBean はもはやシングルトンではありません。今度は MyConfiguration に再び @Configuration アノテーションを付けて MySpringApp クラスを実行します。今度の出力は以下のようになります。

MyBean instance created
MyBeanConsumer created
myBean hashcode = 1095088856

Springコンテナが望むように振る舞っていることを確認するために、構成クラスに @Configuration アノテーションを使用するのが良いです。奇妙な理由で @Configuration アノテーションを使用したくない場合は、myBean() メソッドを呼び出さずに、代わりに @Autowired アノテーションを使用して MyBean を構成したインスタンス変数を使用して構成クラスを作成できます。以下のようなコードも機能します。

package com.journaldev.spring;

import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;

//@Configuration
public class MyConfiguration {

	@Autowired
	MyBean myBean;
	
	@Bean
    public MyBean myBean() {
		return new MyBean();
	}
	
	@Bean
    public MyBeanConsumer myBeanConsumer() {
		return new MyBeanConsumer(myBean);
	}
}

これでSpring Configurationアノテーションに関する説明は終わりです。将来の投稿で他のSpringアノテーションを詳しく見ていきます。

例のコードは当社の GitHubリポジトリ からダウンロードできます。

Source:
https://www.digitalocean.com/community/tutorials/spring-configuration-annotation