Spring FrameworkはJavaアプリケーション開発で人気のフレームワークとなっており、Java経験者の多くが使用したことがあるはずです。
よくBeanなど耳にすることも多いと思いますが、「Beanとは?Springの仕組みを説明せよ」と言われると。。

そんなの、もうアプリ基盤が大体できたところを一部開発してただけだし、あんまり把握してないよう
って方も結構いるのではないでしょうか?
なので、今回はSpringの構成のコア部分をまとめてみました。初心者の方や中級者の方も参考にしてみてください。
Beanとは
Beanとは、Spring コンテナで管理されるオブジェクトのことです。DI(Dependency Injection)の仕組みを使ってこのBeanの依存性を解決します。
この説明を初見で理解出来たらすごいですが、ほとんどの方が理解不能でしょう。
Springコンテナ、DIについて理解をしていないと難しいと思います。
ここでは、Beanを理解する上でキーとなるDIやSpringコンテナについて解説します。
DI(Dependency Injection)とは
さて、DI(Dependency Injection)とはなんでしょうか。
DIは日本語で依存性注入と呼び、オブジェクト指向プログラミング一般に用いられている設計パターンになります。あるクラスが別クラスのオブジェクトを参照している場合に、「依存性がある」と表現し、プログラムを動作させるのに外部から依存性注入(DI)をします。

あれ、普通にクラス内でnewして内部的にインスタンス作成するのとは違うの?
内部的に直接インスタンスを作成するとクラス間の依存性が高くなってしまい、DIの設計方法とは違ってしまいます。DIによって外部から依存性注入をするので、それぞれのクラスを独立させているのです。
Constructor InjectionでDIをするのが一般ですが、その場合は以下のような例になります。
class Test1 {
Test2 test2; // Test1がTest2に依存している
Test1 (Test2 test2) {
this.test2 = test2; // DIしている
}
....
}
class Test2 {
....
}

DIの考え方で実装すれば、そのクラス自体は特に依存しているクラスの実装内容などを意識しなくても良くなるのね
DIには他にもField InjectionやSetter Injectionがありますが、Constructor Injectionは依存クラスが不変(immutable)となるため推奨されています。どうしてもDIしているBeanを実行タイミングに応じて変える必要がある時などは、Setter Injectionを利用するのが良いですね。
SpringではこのDIの仕組みを使ってアプリケーションを管理しており、その管理対象オブジェクトがBeanと呼ばれるものになります。Beanが別のBeanに依存している、つまり参照する必要がある場合にDIが起こります。
では、このBeanを管理しているSpringコンテナとは一体なんでしょうか?
IoC(Inversion of Control)コンテナとは
SpringコンテナはIoC(Inversion of Control)コンテナと呼ばれ、Beanを作成またはDIする役割があります。XMLやJava、Annotationベースの設定ファイルを基にして機能(Bean定義)します。

Inversion of Controlは制御の反転という意味で、Bean1が依存するBean2を呼び出すのではなく、依存するBean2を注入されることで、制御が反転しているというわけだな。

Bean定義方法
前でも触れたように、Bean定義には以下の3つの方法があります。
- XML-Based Configuration
- Annotation-Based Configuration
- Java-Based Configuration
順に説明をしていきます。
XML-Based Configuration
XML(applicationContext.xml)にBeanの設定を書いていきます。
<beans>
<bean id="testService" class="com.services.TestServiceImpl"/>
</beans>
Annotation-Based Configuration
@ComponentをBean化したいクラスに設定します。コンポーネントスキャン後に設定したクラスの「Beanの作成→コンテナに保存」が実行されます。
@Component
public class Test {
...
}
スキャンをするパッケージを指定することも可能です。basePackagesを指定しなければ@ComponentScanが設定されたクラスのパッケージが対象となります。
@Configuration
@ComponentScan(basePackages = "test") //スキャン実施範囲
public class TestConfig {
...
}
@Componentのアノテーション以外には様々な種類があり、クラスの役割に変えるのが一般的です。
各アノテーション定義のソースコードには共通して@Componentが定義されています。
- @Servie
- @Repository
- @Controller
- @RestController
- @Configuration
- etc…
Java-Based Configuration
メソッドの戻り値をBeanで定義する方法になります。対象メソッドに@Beanを定義し、そのクラスに@Conficurationを定義します。
@Configuration
public class TestConfig {
@Bean
public Test getBean() {
return new Test();
}
}
最後に
今回はSpringで開発するにあたり、一番コアとなるBeanやIoCコンテナ、DIについておさらいしました。他にもAOPやMVCなど機能がたくさんありますので、興味を持った方はググってみると良いかもしれません。
コメント