S2Daoの接続先動的切り替え

そういえば、完全におなじテーブル構成のデータベースが2つあるとして、片方をテスト系、片方を本番系として考えたとき、両方に同じBeanとDaoが使えるのは明らかです。で、ある1アプリケーションがその双方にCRUDを行えるようにする、というとき、例えば

  • Daoインタフェースは1つ
  • 異なるDataSourceを明示的に指示した S2DaoInterceptorのセット(実際にはDaoMetaDataFactoryに渡すことが重要)を準備する
  • 異なるS2DaoInterceptorのcomponent定義にあわせて Daoを2つのinterceptorでアドバンスする = Dao interface1種類につき2つのインスタンスを作る

という風にすることで実現できます。

で、ServiceからそのDaoを使う、ということは Serviceは明示的にテスト系本番系切り分けてCRUD行えるような機能を持って Daoは2つinjectionしてもらう方法と、Serviceそのものもテスト系用本番系用分ける方法があります。まあ、前者は接続先が増えたらソースコードもいじらないといけないんでちょっとイヤですよね。後者のほうがdiconの定義だけでいけるから幸せな感じです。

じゃーService実装は1つでコンポーネント定義(=instance)が2つ出来たら今度はそのServiceを使うユーザーである他のServiceやActionが…という風に最終的に「テスト系にUPしたい」「いやいや本番系にUPしたい」「と言うか両方UPしたい」という判断ができる(決める責務がある)クラスまでどんどん遡っていきます。ということは接続先の数が増えると、ソースコードこそ増えないもののコンポーネントの構成は増えます。

んで、アプリケーションの特性が「テスト系か本番系か、ユーザーが指定した場所にあげる」というような場合には DataSourceのgetConnection()を動的にする、という方法がなかなか面白いです。接続先がどちらか、という情報はsessionとかに持っておいて、DataSourceのgetConnection()ではsessionバインディングの「接続先情報」を取得して、それぞれのconnectionPoolからcheckOutしてやるわけです。

私のとこのシステムはこんな感じで動いてますが結構バッチリ動きます。