春の@Configurationアノテーション
Springの@Configurationアノテーションは、Springコアフレームワークの一部です。Springの@Configurationアノテーションは、クラスが@Bean定義メソッドを持っていることを示します。そのため、Springコンテナはクラスを処理し、アプリケーションで使用されるSpring Beansを生成することができます。
春の@Configuration
Springの@Configurationアノテーションは、依存性注入のために注釈を使うことを可能にします。Springの設定クラスを作成する方法を理解しましょう。簡単なJavaビーンクラスを作成しましょう。
package com.scdev.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の設定クラスを作成しましょう。
package com.scdev.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.scdev.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は自分のコンテキストにBeanをロードすることに注意してください。これは、すべてのBeanが適切に設定され、アプリケーションが正常に動作しない場合にはすぐに失敗するようにするためです。また、ctx.refresh()を呼び出さなければ、コンテキストからBeanを取得しようとしたときに以下のエラーが発生します。
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.scdev.spring.MySpringApp.main(MySpringApp.java:11)
MyBeanインスタンスを取得している箇所のコメントを外すと、MyBeanのコンストラクタは呼び出されないことに気付くでしょう。これは、Springのデフォルトのスコープがシングルトンであるためです。@Scopeアノテーションを使用して変更することができます。
@Configurationアノテーションを取り除いた場合はどうなりますか?
もし、MyConfigurationクラスから@Configurationのアノテーションを削除した場合、予想通りに動作し、SpringのBeanがシングルトンクラスとして登録および取得されます。ただし、この場合はmyBean()メソッドを呼び出した場合、単なるJavaのメソッド呼び出しとなり、新しいインスタンスのMyBeanが取得され、シングルトンではなくなります。このことを証明するために、MyBeanのインスタンスを使用する別のBeanを定義しましょう。
package com.scdev.spring;
public class MyBeanConsumer {
public MyBeanConsumer(MyBean myBean) {
System.out.println("MyBeanConsumer created");
System.out.println("myBean hashcode = "+myBean.hashCode());
}
}
私たちの最新のSpring設定クラスは、次のとおりです。
package com.scdev.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.scdev.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の設定アノテーションに関するすべてですが、将来の投稿では他のSpringアノテーションについても見ていきます。
弊社のGitHubリポジトリから、サンプルコードをダウンロードすることができます。