この記事の目的
Springについて②の続きです。
今回はBeanの紐づけについて簡単にまとめます。
Beanの紐づけとは?
前章、前々章ではどのオブジェクトがBeanとして振る舞うか?の指定とそれを保存しておくDIコンテナの振る舞いについてまとめました。
基本となるBeanの注入方法では、ContextConfigurationクラスに対して、Beanのクラスを引数にしてgetBeanメソッドを呼び出していましたが、@Autowiredを用いたオートワイヤリングではどのようにBeanを特定しているのでしょうか?
①型による解決
概要→利用する際に指定したクラスの型で判別する。
使用方法
@Congiguration
@ComponentScan
public class Config{
@Bean
HogeClass hogeClass(){
return new HogeClass();
}
@Bean
FugaClass fugaClass(){
return new FugaClass();
}
}
public class Injection{
@Autowired
HogeClass hogeClass;
@Autowired
FugaClass fugaClass;
}
問題点
指定した型のBeanが存在しない
⇒NoSuchBeanDefinitionExceptionが発生する
指定した型のBeanがコンテナに複数登録されている
⇒NoUniqueBeanDefinitionExceptionが発生する
特に、ある親クラスを継承したクラスが複数ある場合というのはプログラム上で往々にしてあり、その際にいちいちDIをする際にソースコードに子クラスのクラスをべた書きするのはDIの意味がなく、親クラスでBeanをしていするとNoUniqueDefinitionExceptionが発生する、、、といった事態になってしまいます。
これを解決するのが次の手段になります。
②名前による解決
概要→Beanを定義する際に固有の名前を設定し、取り出すときはその名前で指定する
使用方法
@Congiguration
@ComponentScan
public class Config{
@Bean
HogeClass hogeClass(){
return new HogeClass();
}
@Bean
HogeClass fugaClass(){
return new FugaClass();
}
}
public class Injection{
@Autowired
@Qualifer("hogeClass")
HogeClass hoge;
@Autowired
@Qualifer("fugaClass")
HogeClass fuga;
}
上記の場合、どちらもHogeClassを親に持つクラスの為、Qualiferにより名前で紐づけしないとエラーを生じる
名前を個別に指定したいときは下記のようにする
@Congiguration
@ComponentScan
public class Config{
@Bean(name = "hoge1")
HogeClass hogeClass(){
return new HogeClass();
}
@Bean(name = "fuga1")
HogeClass fugaClass(){
return new FugaClass();
}
}
## 次回予告
コンポーネントスキャンの中身やBeanのスコープをまとめていったん終了としたいです