コンストラクタにautowire

コンストラクターインジェクションは年に一度使うか使わないかの体たらくなため、Springのautowire属性はbyTypeかbyNameしかないと思っていたら、"constructor"と"autodetect"というのがある事をいまさら知り、ちょっと調べてみました。


"constructor"は文字通りコンストラクタに対してインジェクションを行うもので、インジェクト対象を決定するためにはbyType(型ベースの解決)を使用します。
ここで問題になるが複数コンストラクタがある場合ですが、使用するコンストラクタは次のように判定しています。

・引数の数が多いものから、引数がすべて型ベースで解決できるかどうかチェック
・すべて解決できたらそのコンストラクタを使用
・解決できない場合、次に長いコンストラクタの引数解決をチェック
・すべてのコンストラクターに対してチェックしてもだめなら、エラー

この場合、引数の数が同じでどちらも解決できるというケースが出てきますが、テストしたところエラーにはならず、どちらかを適当に使用するようです(多分getMethods()で取れた順)


autodetectの方は、コンストラクタインジェクションとプロパティインジェクションを適切に判断してインジェクションしてくれます。
判断は次のように行うようです。

・デフォルトコンストラクタがあるかどうかチェックして、あればプロパティに対して型ベースでインジェクト
・無い場合は、"constructor"と同じ挙動


コンストラクタインジェクション使う場合は、複数コンストラクタを使い分けたりしないで、大抵はコンストラクタ1個用意するだけと思うので、一番引数の多いものをチェックして型が合わなかったらエラー、ぐらいでもいいんじゃないかなと思ったりします。