The Spring Container does not have to instantiate beans via using the new keyword. Some times objects are created from factories. There are two ways to achieve the same - via a static factory method or via an instance factory method.
If were to test the code
In this technique, an instance method of a pre-existing bean is used to create another bean.
Static factory method:
Consider the static method in the SingerFactory classpublic class SingerFactory { public static synchronized Singer createSinger(final String song) { Singer singer = new Singer(); singer.setSong(song); return singer; } }As can be seen the Factory class is now responsible for creation of all Singers. So we now need Beans that are not created by the Spring Container, but only manged by the container. The XML configuration for the same would be:
<bean id="factoryMadeSingerBean" class="com.performer.SingerFactory" factory-method="createSinger" > <constructor-arg value="Wake Me Up When September Ends" /> </bean>The class attribute here refers to the factory class. The factory-method attribute specifies the method to be executed to return the bean. Spring expects to call the method and get an object which it treats as a bean. The constructor arguments specified in the bean definition are the method parameters. In this case it will be used to pass in as arguments to the constructor of the Singer class
If were to test the code
public static void main(String[] args) { XmlBeanFactory beanFactory = new XmlBeanFactory(new ClassPathResource("beans.xml")); IPerformer factoryMadeSingerBean = (IPerformer) beanFactory.getBean("factoryMadeSingerBean"); factoryMadeSingerBean.perform(); }The output indicates that Spring container used the factory method to create the bean.
Creating a singer instance com.performer.Singer@14c1103 singing Wake Me Up When September Ends....The other technique is to use an instance factory method.
In this technique, an instance method of a pre-existing bean is used to create another bean.
<bean id="musician" class="com.performer.Musician"> </bean>
<bean id="duplicateBean" factory-bean="musician" factory-method="createDuplicate" > <constructor-arg ref = "musician3"/> </bean>The factory-bean attribute refers to the bean instance and the factory method refers to the instance factory method. The class attribute must be left empty here. The createDuplicate() method is as below:
public Musician createDuplicate(final Musician musician) { final Musician newMusician = new Musician(); newMusician.setInstrument(musician.getInstrument()); return newMusician; }I executed the bean creation code and saw the output
public static void main(String[] args) { XmlBeanFactory beanFactory = new XmlBeanFactory(new ClassPathResource("beans.xml")); IPerformer duplicateBean = (IPerformer) beanFactory.getBean("duplicateBean"); duplicateBean.perform(); }Output:
Creating new Musiscian Object com.performer.Musician@1592174 Playing instrument Violin...
cool. thanks
ReplyDeletevery nice way to explain about spring factory-bean factory-method.
ReplyDeleteNice..and good example..
ReplyDeleteIf it is possible to use,how to use a non-static method to initialize a particular property of bean?
ReplyDeleteI have bean named "contextstartedhandler" which has a getmessage method which is'nt static(i dont want it to be static as it uses non-static variables of its class) and inside it i'll intialze a "message".How can i specify to intialize this property called message of that bean in the config.xml file in definition
1)
2)
above codes are throwing exception
Sorry, parts of your question are missing. From what I understood, you have a bean 'contextstartedhandler' and want to use its instance method to initialize another bean named 'message'.
ReplyDeleteIf my understanding is right than this is a case of instance factory method.
Very helpful, got me around a problem I was having with instantiating an EasyMock mock with IMocksControl through Spring. Thanks!
ReplyDeletenice job keep it up
ReplyDelete