Spring FactoryBean Example

A factory bean is a bean that serves as a factory for creating other beans within the IoC container. Conceptually, a factory bean is very similar to a factory method, but it is a Spring-specific bean that can be identified by the Spring IoC container during bean construction and can be used by container to instantiate other beans.

Creating beans using FactoryBean

To create a factory bean, all you have to do is to implement the FactoryBean interface by your creator bean class which will be creating actual other beans. Or to keep it simple, you can extend AbstractFactoryBean class.

By extending the AbstractFactoryBean class, your factory bean can simply override the createInstance() method to create the target bean instance. In addition, you have to return the target bean’s type in the getObjectType() method for the auto-wiring feature to work properly.

public class EmployeeFactoryBean extends AbstractFactoryBean<Object>
{
    /This method will be called by container to create new instances
    @Override
    protected Object createInstance() throws Exception
    {
        //code
    }

    //This method is required for autowiring to work correctly
    @Override
    public Class<EmployeeDTO> getObjectType() {
        return EmployeeDTO.class;
    }
}

Why use factory beans?

Factory beans are mostly used to implement framework facilities. Here are some examples:

  1. When looking up an object (such as a data source) from JNDI, you can use JndiObjectFactoryBean.
  2. When using classic Spring AOP to create a proxy for a bean, you can use ProxyFactoryBean.
  3. When creating a Hibernate session factory in the IoC container, you can use LocalSessionFactoryBean.

In most cases, you rarely have to write any custom factory beans, because they are framework-specific and cannot be used outside the scope of the Spring IoC container.

FactoryBean Demo

In this example, I am creating a factory bean to instantiate different types of Employee objects e.g. their manager, director etc. with some pre-populated attributes.

Our EmployeeDTO class looks like this.

package com.howtodoinjava.demo.model;

public class EmployeeDTO {

	private Integer id;
	private String firstName;
	private String lastName;
	private String designation;

	//Setters and Getters are hidden behind this comment.

	@Override
	public String toString() {
		return "Employee [id=" + id + ", firstName=" + firstName
				+ ", lastName=" + lastName + ", type=" + designation + "]";
	}
}

EmployeeFactoryBean class extends AbstractFactoryBean class and implements it’s two methods createInstance() and getObjectType().

import org.springframework.beans.factory.config.AbstractFactoryBean;

import com.howtodoinjava.demo.model.EmployeeDTO;

public class EmployeeFactoryBean extends AbstractFactoryBean<Object> 
{
	private String designation;
	
	public String getDesignation() {
		return designation;
	}

	public void setDesignation(String designation) {
		this.designation = designation;
	}

	//This method will be called by container to create new instances
	@Override
	protected Object createInstance() throws Exception 
	{
		EmployeeDTO employee = new EmployeeDTO();
		employee.setId(-1);
		employee.setFirstName("dummy");
		employee.setLastName("dummy");
		//Set designation here
		employee.setDesignation(designation);
		return employee;
	}

	//This method is required for autowiring to work correctly
	@Override
	public Class<EmployeeDTO> getObjectType() {
		return EmployeeDTO.class;
	}
}

You will define various Employee types in context file as below.

<bean id="manager"  class="com.howtodoinjava.demo.factory.EmployeeFactoryBean">
	<property name="designation" value="Manager" />
</bean>

<bean id="director"  class="com.howtodoinjava.demo.factory.EmployeeFactoryBean">
	<property name="designation" value="Director" />
</bean>

To test above factory beans, use below code:

public class TestSpringContext 
{
	@SuppressWarnings("resource")
	public static void main(String[] args) 
	{
		ApplicationContext context = new ClassPathXmlApplicationContext("applicationContext.xml");

		EmployeeDTO manager = (EmployeeDTO) context.getBean("manager");
		System.out.println(manager);
		
		EmployeeDTO director = (EmployeeDTO) context.getBean("director");
		System.out.println(director);
	}
}

Output:

Employee [id=-1, firstName=dummy, lastName=dummy, type=Manager]
Employee [id=-1, firstName=dummy, lastName=dummy, type=Director]

As you can see that EmployeeFactoryBean created two different employee objects using same factory method.

Getting FactoryBean instance itself

If you want to get the instance of EmployeeFactoryBean itself, then you can add an “&” before the bean name.

EmployeeFactoryBean factory = (EmployeeFactoryBean) context.getBean("&director");

System.out.println(factory.getDesignation());
System.out.println(factory.getObjectType());
System.out.println(factory.getObject());

Output:

Director

class com.howtodoinjava.demo.model.EmployeeDTO

Employee [id=-1, firstName=dummy, lastName=dummy, type=Director]

Drop me your queries in comments section.

Happy Learning !!

Leave a Reply

3 Comments
Most Voted
Newest Oldest
Inline Feedbacks
View all comments

About Us

HowToDoInJava provides tutorials and how-to guides on Java and related technologies.

It also shares the best practices, algorithms & solutions and frequently asked interview questions.

Our Blogs

REST API Tutorial