Issue
I am learning spring (and following Spring in Action), As I was playing around to understand few concept; then I observed following behavior.
Scenario:
I wanted to autowire a list property in a Class by using "byType" autowire option. so I created util:list bean; which successfully get injected... so no surprise here :).
Then I added a new list property in the same class(of different class hierarchy: off-course); then that too get injected without doing any extra wiring.... :O
Can any body explain whats going on under the hood.
Below is some code snippt.
public interface Performer {
public void perform();
}
public interface Instrument {
public void play();
}
public class Show implements Audotorium {
Logger logger = Logger.getLogger(Show.class.getName());
List<Performer> performerList;
List<Instrument> instruments;
public void setPerformerList(List<Performer> performerList) {
this.performerList = performerList;
}
public void setInstruments(List<Instrument> instruments) {
this.instruments = instruments;
}
public void show() {
Iterator<Performer> performerItr = performerList.iterator();
while (performerItr.hasNext()) {
performerItr.next().perform();
}
Iterator<Instrument> instrumentItr = instruments.iterator();
while (instrumentItr.hasNext()) {
instrumentItr.next().play();
}
}
}
Main Class
public static void main(String[] args) {
ApplicationContext context = new ClassPathXmlApplicationContext("/META-INF/spring-context.xml");
((Show) context.getBean("show")).show();
}
Bean Configration:
<bean id="juggler" class="com.learning.Juggler"/>
<bean id="magcian" class="com.learning.Magician"/>
<bean id="kenny" class="com.learning.Instrumentalist">
<property name="song" value="bay finger bay finger"/>
<property name="instrument" ref="saxphone"/>
</bean>
<bean id="hunk" class="com.learning.OneManBand" autowire="byType">
<property name="song" value="bay finger bay finger"/>
<property name="instruments">
<list>
<ref bean="saxphone"/>
<ref bean="guitar"/>
<ref bean="harmonica"/>
</list>
</property>
</bean>
<bean id="totalBeanBags" class="java.lang.Integer" factory-method="valueOf">
<constructor-arg value="#{performerList.size()}"/>
</bean>
<bean id="saxphone" class="com.learning.SaxPhone"/>
<bean id="guitar" class="com.learning.GenaricInstument">
<property name="instrumentSound" value="guitar sound"/>
</bean>
<bean id="harmonica" class="com.learning.GenaricInstument">
<property name="instrumentSound" value="harmonica sound"/>
</bean>
<util:list id="performerList"/>
<bean id="show" class="com.learning.Show" autowire="byType">
</bean>
Output:
JUGGLING 10 BEANBAGS
Showing some crazy magicSSsssSSSsss.....
Playing bay finger bay finger : TOO TOO TOO
Playing bay finger bay finger : TOO TOO TOO
guitar sound
harmonica sound
----Now its music time----
TOO TOO TOO
guitar sound
harmonica sound
Solution
With
<util:list id="performerList"/>
you create an empty list, it is not used, you could remove it.
You have one bean of type Performer
the 'OneManBand'.
When spring tries to autowire setPerformerList
, it automatically creates a list of type List<Performer>
and uses it as parameter. Spring puts all beans of type Performer
into that list.
A list of Instrument
is created and injected the same way.
This is a very handy feature of spring, I use it offen to build registries that collect all beans of a certain type and act on them.
Answered By - Stefan Isele - prefabware.com
Answer Checked By - Mildred Charles (JavaFixing Admin)