Spring Framework 入門記 Beanその4 depends-on,autowire,dependency-check

コンテナの動きを調整する<bean>要素の属性がいくつかあります.

  • depends-on属性

depends-on属性は,Beanの初期化順に依存関係がある場合に使用します.constructor-basedではあまり問題にならないと思いますが,setter-basedでBeanの参照を設定する場合には,初期化順の依存関係が問題になる場合が考えられます.例えばAとBという2つのBeanがあり,AはBへの参照をプロパティに持っているとします.つまり,AはsetB(B)というsetterを持つわけですが,このsetterの中で,Bのプロパティにアクセスしたり,メソッドを呼び出したりするかもしれません.ということは,AのsetB(B)が呼び出されたときには,Bのプロパティの設定は完了していないといけないわけです.このような場合,AはBに依存していることを,depends-on属性で明示します.

    

depends-onで指定する値は,<ref>要素のbean属性と同じく,Beanの名前です(「Spring Framework 入門記 Beanその1 id/name属性とsingleton属性」を参照).
Apache AvalonECM(Excalibur Compoenent Manager)ではコンポーネントの初期化順を制御できなかったので(たぶん),これはありがたいです.

  • autowire属性

setter-basedでもconstructor-basedでも,他のBeanへの参照を設定することができます.これまでは,参照するBeanを<ref>属性で明示的に指定していたわけですが,これをコンテナにお任せすることができます.これをautowiringと呼びます.このためにautowire属性を使用することができます.
autowire属性には,次の値を指定することができます.

no
デフォルトです.autowiringは行いません.
byName
Beanの名前でautowiringを行います.
byType
Beanの型でautowiringを行います.

byNameを指定すると,そのBeanのプロパティ名と一致する名前を持つBeanがあれば,それをプロパティに設定してくれます.
byTypeを指定すると,そのBeanのプロパティの型と一致するBeanが(一つだけ)あれば,それをプロパティに設定してくれます.ただし,プロパティの型と一致するBeanが複数あると,またしても例外が吹っ飛んできます.
一見便利そうなautowiringですが,個人的にはあまり魅力を感じません.ないよりはあってもいい,くらいの感じです.というのも,ある程度Beanの数が増えてくると,byNamebyTypeとも使えないことになると思うからです.byNameは,参照する側のBeanのインスタンスが複数あり,それぞれのプロパティに異なった値を設定する場合に使えなくなります.byTypeは,参照される側のBeanのインスタンスが複数ある場合に使えなくなります.ちょっとしたサンプル程度なら楽ができるとは思うのですが,その程度だったら明示的に指定してもたいした手間がかかるわけではないわけですから,結局大きなメリットにはならないと思うわけです.

  • dependency-check属性

属性名からはピンときませんが,この属性により,Beanのプロパティの設定漏れをコンテナにチェックしてもらうことができます.Dependency Injectionのdependencyということで全く正しいのだと思いますが,なんだかピンとこないんですよね.
dependency-check属性には,次の値を指定することができます.

none
プロパティの設定漏れをチェックしません.
simple
プリミティブ型およびjava.lang.String型のプロパティに設定漏れがないかチェックします.
objects
java.lang.String以外のオブジェクト(参照)型のプロパティに設定漏れがないかチェックします.
default
デフォルトです.noneと同様,設定漏れをチェックしません.

Spring Framework Reference Documentation」の「Checking for dependencies」ではobjectsではなくobjectとなっていますが,DTDではobjectsとなっています.また,simpleはプリミティブ型に加えてコレクション型のプロパティをチェックするとなっていますが,1.0RC2ではコレクション型はチェックされず,代わりに(?)java.lang.String型のプロパティがチェックされます.このあたりの説明は,DTD中のコメントの方が実装と一致しているようです.
dependency-checkもありがたいようで,実はそれほどでもない感じです.プロパティに値や参照を設定していないことをチェックするということは,それらのプロパティにデフォルト値がないために,明示的に設定することを強制したいということだと思います.それはよくある状況です.しかし,そのような状況はクラス単位で出てくる話だと思うのですね.ですが,dependency-check属性は<bean>要素の属性です.つまり,インスタンス単位で設定します.とあるインスタンスの設定(<bean>要素)で,dependency-check属性の指定が漏れてしまったら,全然意味がありません.このようなチェックが必要であれば,そのクラスのコンストラクタで強制するのが適当だと思います.


今回は,コンテナの動作を調整する<bean>要素の3つの属性について学習しました.
現時点ではdepends-on属性以外はあまり使う価値を感じませんが,経験を深めていくと考えが変わるかどうか... 将来のお楽しみということで.
次はライフサイクルにするかBigDecimalを扱うPropertyEditorを作るか.明日の気分で決めたいと思います.