DI コンテナに Spring を利用した場合に Doma2 で複数のデータソースを使おうとしたら、ハマったので。
要件
- 複数のデータソースに対し Doma の Dao で操作したい。
- DB 接続情報を記載した設定ファイルのロードは Spring にあやかりたい。
うまくいった方法
必要な DataSource ぶんの Config を返す Bean アノテーションのついたメソッドを定義。通常 AppConfig みたいな名前のクラスに実装しがちなあれ。
このメソッド名はのちに Qualifier で指定することになる。
@Bean
public Config mainDbConfig() {
return new Config() {
// データソースかえしたりする.
};
}
Doma の Dao のインタフェースに以下のアノテーションを付ける。
最後の elements で指定している部分が、上で定義したメソッド名になる。
通常1つのデータソースに複数 Dao クラスが存在すると思うので、別のわかりやすいアノテーションを定義して、それをそれぞれの Dao クラスに付与することになると思う。
@AnnotateWith(annotations = {
@Annotation(target = AnnotationTarget.CLASS, type = Repository.class),
@Annotation(target = AnnotationTarget.CONSTRUCTOR, type = Autowired.class),
@Annotation(target = AnnotationTarget.CONSTRUCTOR_PARAMETER, type = Qualifier.class, elements = "\"mainDbConfig\"")
})
@Dao
public interface HogeDao {
すると、Doma により以下の様なコンストラクタを持つ HogeDaoImpl が作られる。
(完全修飾名で読みづらい部分は端折た)
@Autowired()
public HogeDaoImpl(@Qualifier("mainDbConfig") Config config) {
super(config);
}
というわけで、Dao クラスのインスタンスが生成されるときに、コンストラクタに Qualifier で指定された Bean を渡してもらえる。
うまくいかなかった方法
Dao アノテーションに Config を実装したクラスを
@Dao(config = HogeConfig.class)
とするような方法をとろうと
org.seasar.doma.jdbc.Config を実装したクラスをデータソース分定義すると、
No qualifying bean of type 〜
と Spring に怒られる。。。
Qualifier を XML に書いたりしてみてもうまく行かず。。。
???
- Spring-load で実行すると挙動が不審? (動いてるようだけど度々例外が...)