Creating Beans by Invoking an Instance Factory Method

You can write the following ProductCreator class by using a configurable map to store the predefined products. The createProduct() instance factory method finds a product by looking up the supplied productId in the map. If there is no product matching this ID, it will throw an IllegalArgumentException.

package com.shop;
public class ProductCreator {
private Map<String, Product> products;
public void setProducts(Map<String, Product> products) {
this.products = products;
}
public Product createProduct(String productId) {
Product product = products.get(productId);
if (product != null) {
return product;
}
throw new IllegalArgumentException("Unknown product");
}
}

To create products from this ProductCreator class, you first have to declare an instance of it in the IoC container and configure its product map. You may declare the products in the map as inner beans. To declare a bean created by an instance factory method, you specify the bean hosting the factory method in the factory-bean attribute, and the factory method’s name in the factory-method attribute. Finally, you pass the method arguments by using the <constructor-arg> elements.

<beans …>
<bean id="productCreator"
class="com.shop.ProductCreator">
<property name="products">
<map>
<entry key="aaa">
<bean class="com.shop.Battery">
<property name="name" value="AAA" />
<property name="price" value="2.5" />
</bean>
</entry>
<entry key="cdrw">
<bean class="com.shop.Disc">
<property name="name" value="CD-RW" />
<property name="price" value="1.5" />
</bean>
</entry>
</map>
</property>
</bean>
<bean id="aaa" factory-bean="productCreator"
factory-method="createProduct">
<constructor-arg value="aaa" />
</bean>
<bean id="cdrw" factory-bean="productCreator"
factory-method="createProduct">
<constructor-arg value="cdrw" />
</bean>
</beans>

In case of any exception thrown by the factory method, Spring will wrap it with a BeanCreationException. The equivalent code snippet for the preceding bean configuration is shown following:

ProductCreator productCreator = new ProductCreator();
productCreator.setProducts(…);
Product aaa = productCreator.createProduct("aaa");
Product cdrw = productCreator.createProduct("cdrw");