-S05: 車がぶつかりました

list05-1. 同一インターフェイスを持つ実装クラスを複数登録でNG
<?xml version="1.0" encoding="UTF-8"?>
<components>
  <component class="tutorial.org.seasar.console.HelloCar"/>
  <component class="tutorial.org.seasar.console.GoodbyCar"/>
</components>

一方、設定XMLをlist05-1のように書くと実行時例外です。

org.seasar.framework.container.TooManyRegistrationRuntimeException: [ESSR0045]interface tutorial.org.seasar.console.Carに複数のコンポーネント(tutorial.org.seasar.console.HelloCar, tutorial.org.seasar.console.GoodbyCar)が登録されています

このTooManyRegistrationRuntimeExceptionは同じキーに複数コンポーネントが登録されている場合に、そのキーでgetComponent(*)が呼び出されると生成される実行時例外です。この場合、list03-1のHighwayクラスで、Carインターフェイスをキーとしてコンポーネント取得(getComponent(Car.class))をしてますが、list05-1ではそのCarインターフェイスを実装したクラスが、HelloCarおよびGoodbyCarの二つ登録されているために例外が発生しています。ここで重要なのはインターフェイスが重複しているという事実と、TooManyRegistrationRuntimeExceptionが発生するのはコンポーネントの取得時であって、登録時ではないことです。この場合の対応としては、単純に設定XMLをlist03-4もしくはlist04-7のようにどちらか一つにしてインターフェイスの重複を避けるという対応だけでなく、コンポーネント名を利用した取得方法に変更することで重複登録の解決も考えられます。すなわち、list05-2のとおりです。

list05-2. 同一インターフェイスを持つ実装クラスを複数登録でもOK
<?xml version="1.0" encoding="UTF-8"?>
<components>
  <component name="helloCar" class="tutorial.org.seasar.console.HelloCar"/>
  <component name="goodbyCar" class="tutorial.org.seasar.console.GoodbyCar"/>
</components>

Highwayクラスのmainメソッド中で行う処理
Car helloCar = (Car)container.getComponent("helloCar");
Car goodbyCar = (Car)container.getComponent("goodbyCar");

S2Containerの利用側コード(Highwayクラス)も変更が必要ですから、システム全体のコンポーネント配置設計は注意深く行わなければなりません。名前を利用する場合も、同じ名前でコンポーネントを登録してしまった場合は、その重複名でgetComponent(String)を実行した時点でTooManyRegistrationRuntimeExceptionが発生してしまいます。
インターフェイスクラスおよび名前どちらでも重複したキーに対しては、内部的にはTooManyRegistrationComponentDefオブジェクトがセットされ、重複リストを保持します。この重複リストが例外発生時にメッセージに現れるコンポーネントのリストとなります。つまり、キー(Car)&値(TooManyRegistrationComponentDef [HelloCar, GoodbyCar])などのようにセットされてしまっている場合にgetComponent(Car.class)とすると、TooManyRegistrationRuntimeExceptionは取得キーのCarとリスト保持された[HelloCar, GoodbyCar]を例外メッセージに表示します。