Quicksort in java
Java

Spring FactoryBean: A Guide for Developers

Introduction

A Spring FactoryBean is a special kind of bean that acts as a factory for creating other beans. The Spring Framework is one of the most popular Java frameworks for the development of enterprise applications. It offers extensive support for Dependency Injection (DI) and Bean Lifecycle Management, making it easier for developers to create scalable and maintainable applications. One of the powerful but lesser-known features of the Spring bean management system is the FactoryBean interface.

When we work with Spring, we usually define beans using annotations (@Component, @Service, @Repository, etc.) or through Java and XML configuration. However, there are cases where we need a more flexible and controlled way to create beans — this is where FactoryBean comes into play.

Instead of defining a bean directly, we define a FactoryBean that produces and manages the creation of a bean. This approach is particularly useful when working with complex objects, expensive resources or objects that require special initialization logic.

What you will learn in this post

In this blog post, we will explore the following:
What FactoryBean is and how it works.
Why and when to use a FactoryBean in Spring applications.
How to implement your own FactoryBean with examples.
Differences between FactoryBean and Factory Method.
Some of the most commonly used built-in FactoryBeans in Spring.
Best practices and common pitfalls to avoid when using FactoryBean.

By the end of this post, you’ll have a solid understanding of how FactoryBean works and how to use it effectively in your Spring applications. Let’s dive in!

What is a FactoryBean in Spring?

In a typical Spring application, we define beans using configuration files (XML or Java based) and let the Spring container manage their instantiation, dependencies and lifecycle. However, there are cases where creating a bean requires additional logic, such as:

  • Constructing a complex object that depends on external configurations.
  • Wrapping a third-party library that does not integrate smoothly with Spring’s dependency injection.
  • Implementation of proxy objects for AOP (Aspect-Oriented Programming) or transaction management.

This is where FactoryBean comes into play.

Definition of FactoryBean

A FactoryBean is a special Spring bean that serves as a factory for creating objects. Instead of being a normal bean instance, it produces another object (the target bean) and provides Spring with a way to manage its lifecycle.

Unlike normal beans, where Spring instantiates the class directly, a FactoryBean allows developers to control how an object is created and initialized. This is particularly useful when an object cannot simply be created with the new keyword or requires special post-processing.

How does FactoryBean work?

Spring treats beans that implement FactoryBean differently from normal beans. When a FactoryBean is defined in the Spring container, it does not expose itself as a bean. Instead, it exposes the object it creates.

Key concept:

  • A FactoryBean is itself a bean, but it is not the object that is injected into dependent beans.
  • Spring calls the getObject() method on the FactoryBean to get the actual object it is supposed to manage.
  • The resulting object can be a Singleton (shared instance) or a Prototype (new instance per request) depending on the configuration.

Core methods of FactoryBean

To implement a FactoryBean, you need to override three important methods:

methodpurpose
T getObject()Creates the bean instance to be published and returns it.
Class getObjectType()Returns the type of the object created by this factory.
boolean isSingleton()Specifies whether the created object should be a singleton or a prototype.

Example: A simple FactoryBean implementation

import org.springframework.beans.factory.FactoryBean;

public class MyFactoryBean implements FactoryBean {

 @Override
 public MyService getObject() throws Exception {
 return new MyService(); // Custom object creation logic
}

 @Override
 public Class getObjectType() {
 return MyService.class;
 }

 @Override
 public boolean isSingleton() {
 return true; // Return false for the prototype scope
 }
}

Here MyFactoryBean implements the FactoryBean, which means that it creates an instance of MyService.

The most important findings

  • FactoryBean is a special kind of Spring Bean that creates and manages another Bean.
  • It provides a way to customize object instantiation within the Spring container.
  • The Spring container calls getObject() to get the actual bean instance.
  • You can control whether the bean is a Singleton or a Prototype by overriding isSingleton().

In the next section, we will look at why you need a FactoryBean and what use cases there are.

Why use a FactoryBean?

The FactoryBean mechanism in Spring is useful when the instantiation of beans requires additional control beyond the typical constructor or setter-based injection. Although most beans in Spring applications are defined with a simple class instantiation, there are cases where the standard approach is not sufficient.

Let’s look at the main reasons why you need a FactoryBean and when it is preferable to direct bean creation.

Common use cases for FactoryBean

Creating complex objects

Some objects need to be set up additionally after instantiation. A FactoryBean allows you to encapsulate the complexity of object creation and keep the configuration clean at the same time.

Example: Suppose you need to create a database connection object that needs to read credentials from an external service before initialization.

public class DataSourceFactoryBean implements FactoryBean {

 @Override
 public DataSource getObject() throws Exception {
 String url = fetchDatabaseUrl(); // Fetch URL dynamically
 String user = fetchUser(); // Fetch credentials
 String password = fetchPassword();
 return new DataSource(url, user, password);
 }

 @Override
 public Class getObjectType() {
 return DataSource.class;
 }

 @Override
 public boolean isSingleton() {
 return true;
 }
}

Here, the factory ensures that the DataSource object is fully initialized before it is injected into dependent beans.

Wrapping of third-party libraries

Sometimes third-party libraries do not follow the Spring pattern for instantiating beans, which makes direct integration difficult. A FactoryBean can close the gap by taking over their setup.

Example: You need to integrate an encryption library that requires a factory to initialize encryption keys.

public class EncryptionServiceFactoryBean implements FactoryBean {

 @Override
 public EncryptionService getObject() {
 EncryptionService encryptionService = new EncryptionService();
 encryptionService.initializeKeys(); // Custom setup
 return encryptionService;
 }

 @Override
 public Class getObjectType() {
 return EncryptionService.class;
 }

 @Override
 public boolean isSingleton() {
 return true;
 }
}

This ensures that the EncryptionService is created correctly and can be used in the Spring context.

Implementation of proxies for AOP and transactions

Spring relies heavily on dynamic proxies to enable Aspect-Oriented Programming (AOP), transaction management and security features. the FactoryBean` plays an important role in the creation of proxy objects.

Example: Spring’s ProxyFactoryBean creates proxy objects for method-level security.

<bean id="transactionProxy" class="org.springframework.aop.framework.ProxyFactoryBean">
    <property name="target" ref="myService"/>
    <property name="interceptorNames">
        <list>
            <value>transactionInterceptor</value>
        </list>
    </property>
</bean>

This FactoryBean dynamically creates a proxy for myService and applies transaction management in the background.

Manage expensive resource creation

Some objects are expensive to create, e.g. database connections, thread pools or caches. A FactoryBean can manage their lifecycle efficiently.

Example: If an expensive calculation is needed when initializing a bean, a FactoryBean ensures that it is only executed when needed.

public class ExpensiveResourceFactoryBean implements FactoryBean {

 private ExpensiveResource instance;

 @Override
 public ExpensiveResource getObject() {
 if (instance == null) {
 instance = new ExpensiveResource();
 instance.initialize(); // Simulating an expensive setup
 }
 return instance;
 }

 @Override
 public Class getObjectType() {
 return ExpensiveResource.class;
 }

 @Override
 public boolean isSingleton() {
 return true;
 }
}

This ensures that the ExpensiveResource is only created once and reused.

Advantages of the FactoryBean

Encapsulation of the creation of complex objects: The configuration remains clean and modular.
Better control over bean instantiation: You can initialize objects dynamically instead of relying on direct constructor calls.
Performance optimization: Helps to efficiently manage the creation of expensive objects.
Seamless third-party integration: Integrates external libraries that are not Spring-friendly.
Improved AOP and proxying support: Facilitates Spring internal mechanisms such as transaction management and security.

When should you not use a FactoryBean?

While FactoryBean is powerful, it is not always necessary. You should not use it if:
The object can be instantiated directly with a simple new call.
No additional setup or special initialization is required.
Spring already provides built-in support for the required functionality (e.g. the @Bean configuration for simple objects).

Implementation of a simple FactoryBean

Now that we know what a FactoryBean is and why it is useful, let’s go through the implementation step by step. In this section we will:

  • Create a custom FactoryBean.
  • Register it in the Spring container.
  • Retrieve and use the bean created by the factory.

Example use case

Suppose we need to create an instance of the DatabaseConnection class. The connection data (e.g. URL, username and password) may need to be retrieved from an external source (e.g. a configuration file or an environment variable). Instead of instantiating the DatabaseConnection class manually, we can delegate this task to a FactoryBean.

Creating the DatabaseConnection Class

First, let’s define a simple class that represents a database connection:

public class DatabaseConnection {
 private String url;
 private String username;
 private String password;

 public DatabaseConnection(String url, String username, String password) {
 this.url = url;
 this.username = username;
 this.password = password;
 }

 public void connect() {
 System.out.println("Connect to the database at " + url + " with user " + username);
 }
}

This class requires certain parameters (url, username and password) during instantiation.

Creating the FactoryBean

Next, we create a custom FactoryBean that will be responsible for creating DatabaseConnection objects.

import org.springframework.beans.factory.FactoryBean;

public class DatabaseConnectionFactoryBean implements FactoryBean {

 private String url;
 private String username;
 private String password;

 // Setter for dependency injection
 public void setUrl(String url) {
 this.url = url;
 }

 public void setUsername(String username) {
 this.username = username;
 }

 public void setPassword(String password) {
 this.password = password;
 }

 @Override
 public DatabaseConnection getObject() {
 return new DatabaseConnection(url, username, password);
 }

 @Override
 public Class getObjectType() {
 return DatabaseConnection.class;
 }

 @Override
 public boolean isSingleton() {
 return true; // Return false for prototype instances
 }
}

Explanation:

  • The DatabaseConnectionFactoryBean implements the FactoryBean.
  • It defines the required properties (url, username, password), which can be injected via setters.
  • The getObject() method creates an instance of DatabaseConnection and returns it.
  • The method getObjectType() tells Spring that this factory creates objects of the type DatabaseConnection.
  • The isSingleton() method specifies whether the object should be a singleton (shared instance) or a prototype (new instance per request).

Registration of the FactoryBean in Spring

Now that we have our factory, we need to register it in the Spring container. We can do this with the XML-based configuration or the Java-based configuration.

XML-based configuration

<bean id="databaseConnectionFactory" class="com.example.DatabaseConnectionFactoryBean">
    <property name="url" value="jdbc:mysql://localhost:3306/mydb"/>
    <property name="username" value="admin"/>
    <property name="password" value="secret"/>
</bean>

<bean id="databaseConnection" factory-bean="databaseConnectionFactory" factory-method="getObject"/>

Here:

  • databaseConnectionFactory is the actual FactoryBean.
  • databaseConnection is the bean created by the factory (which is retrieved using getObject()).

Java-based configuration (Spring @Configuration Class)

import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;

@Configuration public class AppConfig {

 @Bean
 public DatabaseConnectionFactoryBean databaseConnectionFactory() {
 DatabaseConnectionFactoryBean factoryBean = new DatabaseConnectionFactoryBean();
 factoryBean.setUrl("jdbc:mysql://localhost:3306/mydb");
 factoryBean.setUsername("admin");
 factoryBean.setPassword("secret");
 return factoryBean;
 }

 @Bean
 public DatabaseConnection databaseConnection(DatabaseConnectionFactoryBean factoryBean) throws Exception {
 return factoryBean.getObject();
 }
}
  • The databaseConnectionFactory() method registers the DatabaseConnectionFactoryBean as a bean.
  • The method DatabaseConnection() retrieves the current instance of DatabaseConnection.

Retrieving the bean from the Spring context

Once the factory bean is registered, we can retrieve the DatabaseConnection object from the Spring context.

import org.springframework.context.ApplicationContext;
import org.springframework.context.annotation.AnnotationConfigApplicationContext;

public class Main {
 public static void main(String[] args) throws Exception {
 ApplicationContext context = new AnnotationConfigApplicationContext(AppConfig.class);

DatabaseConnection connection = context.getBean(DatabaseConnection.class);
 connection.connect(); // Output: Connection to the database at jdbc:mysql://localhost:3306/mydb with user admin
 }
}

Spring automatically calls getObject() on FactoryBean so that DatabaseConnection is injected into the dependent beans instead of DatabaseConnectionFactoryBean.

Retrieving the FactoryBean itself

What if we need to retrieve the actual FactoryBean instead of the object it creates?

Spring offers a special way to do this:

DatabaseConnectionFactoryBean factoryBean = (DatabaseConnectionFactoryBean) context.getBean("&databaseConnectionFactory");
  • Adding “&” in front of the bean name tells Spring to return the FactoryBean itself and not the object it creates.
  • This is useful when we need to dynamically check or change the behavior of the factory.

FactoryBean vs. Factory Method: Main differences

When working with Spring, we often hear about two different ways to dynamically create and manage objects:

  1. FactoryBean (a special Spring interface that provides custom bean creation logic).
  2. FactoryMethod (a static or instance method that returns an object and is typically used in @Bean definitions).

Although both approaches allow for customization of object creation, they are fundamentally different in the way they integrate with Spring’s bean management system.

In this section, we will explore the key differences between these two approaches and when one is preferable to the other.

What is a factory method?

A factory method is simply a method that returns an instance of a class, usually within a Spring configuration class (@Configuration). It can be:
Static – It is called on a class without requiring an instance.
Instance-based – Called for an existing object.

Example: Static factory method in Java

public class CarFactory {
 public static CreateCar() {
 return new Car("Tesla", "Model S");
 }
}

Here, the createCar() method acts as a static factory method that returns a Car object.

Example: Using the factory method in the Spring Java configuration

import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;

@Configuration public class AppConfig {

 @Bean
 public Car car() {
 return CarFactory.createCar(); // Using static factory method
 }
}
  • The car() method functions as a factory method and is registered as a Spring bean.
  • Whenever Spring needs a Car bean, it calls CarFactory.createCar() to create an instance.
What happens here?
  • Spring calls the factory method once during the initialization of the bean.
  • The factory method delivers the actual object (Car), which is then managed as a Spring bean.

What is a FactoryBean?

A FactoryBean is a Spring-specific interface that provides extended control over object creation. Instead of returning the object directly (like a factory method), a FactoryBean:

  1. Implements FactoryBean to define its own instantiation logic.
  2. Is itself a Spring bean, but represents another bean (the one it creates).
  3. Uses Spring’s lifecycle management and supports singleton/prototype scope, lazy initialization, etc.

Example: FactoryBean for Car

import org.springframework.beans.factory.FactoryBean;

public class CarFactoryBean implements FactoryBean {

 @Override
 public Car getObject() {
 return new Car("Tesla", "Model S");
 }

 @Override
 public Class getObjectType() {
 return Car.class;
 }

 @Override
 public boolean isSingleton() {
 return true;
 }
}
  • Instead of defining a factory method, we implement the FactoryBean interface.
  • Spring will call getObject() to get the actual Car instance.

Registration of the FactoryBean in the Java configuration

@Configuration public class AppConfig {

 @Bean
 public CarFactoryBean carFactoryBean() {
 return new CarFactoryBean();
 }

 @Bean
 public Car car(CarFactoryBean factoryBean) throws Exception {
 return factoryBean.getObject(); // Retrieve the created object
 }
}

Main differences between FactoryBean and Factory method

FeatureFactoryBeanFactory Method
Spring IntegrationImplements FactoryBeanRegular method within the class @Configuration
Bean instantiationSpring calls getObject() on the FactoryBeanSpring calls the method directly
Can it be a bean itself?Yes, FactoryBean is registered as a beanNo, only the created object is registered as a bean
UsesProxy objects, complex initialization, dynamic objectsSimple object creation, static factory methods
Get the factory itselfUse &beanName to get the FactoryBeanNo special call needed
Supports singleton/prototype?Yes, via isSingleton() methodControlled via @Scope annotation
When to Use?If an object requires complex instantiation logicIf an object can be created with a simple factory method

When should you use FactoryBean vs. factory method?

Use a FactoryBean when:

  • You need fine-grained control over bean instantiation (e.g. when creating dynamic proxies).
  • The bean requires elaborate initialization and should be created lazily.
  • The bean requires a runtime configuration before it is instantiated.
  • You need a third-party object wrapper that does not integrate smoothly with Spring.

Use Factory Method when:

  • The object can be created with a simple method call.
  • The bean does not require Spring Lifecycle Control.
  • You prefer a cleaner and simpler approach to instantiating objects.

Spring’s Built-in FactoryBeans

Spring provides several built-in FactoryBean implementations to help developers create common objects more efficiently. These FactoryBean classes abstract away the complex instantiation logic for commonly used objects, such as proxy objects, JDBC connections, JNDI lookups, and more.

In this section, we will explore some of the most commonly used FactoryBean implementations in Spring.

Overview of the built-in FactoryBeans

Here are some of the major built-in FactoryBean implementations in Spring:

FactoryBean NamePurpose
ProxyFactoryBeanCreates dynamic proxy objects for AOP (Aspect-Oriented Programming) and method interception.
TransactionProxyFactoryBeanWraps a bean with a transactional proxy and thus enables declarative transaction management.
JndiObjectFactoryBeanSearches and retrieves objects from a JNDI (Java Naming and Directory Interface) environment.
LocalSessionFactoryBeanConfigures and manages the SessionFactory of Hibernate.
SqlSessionFactoryBeanUsed in MyBatis to configure the SqlSessionFactory.
ServiceLocatorFactoryBeanCreates service locator instances that are delegated to Spring-managed beans.
BeanFactoryPostProcessorEnables the customization of bean definitions before the beans are instantiated.
ProxyFactoryBeanCreation of AOP proxies

Spring’s ProxyFactoryBean is one of the most commonly used implementations of the FactoryBean. It is used to create dynamic proxy objects, which are essential for Aspect Oriented Programming (AOP), method security and transaction management.

Example: Creating a proxy for a service

<bean id="myService" class="com.example.MyService"/>

<bean id="proxyService" class="org.springframework.aop.framework.ProxyFactoryBean">
    <property name="target" ref="myService"/>
    <property name="interceptorNames">
        <list>
            <value>myMethodInterceptor</value>
        </list>
    </property>
</bean>

Here:

  • ProxyFactoryBean creates a Proxy object for MyService.
  • The proxy applies an interceptor (myMethodInterceptor) to dynamically change the method behavior.

When to use?

  • When implementing AOP, logging or security logic.
  • When creating transactional proxies.

TransactionProxyFactoryBean – Activate transaction management

If you want to use transactions declaratively in Spring (without using annotations), TransactionProxyFactoryBean will help you by creating transactional proxies.

Example: Transaction management with TransactionProxyFactoryBean

<bean id="transactionManager" class="org.springframework.orm.jpa.JpaTransactionManager">
    <property name="entityManagerFactory" ref="entityManagerFactory"/>
</bean>

<bean id="transactionProxy" class="org.springframework.transaction.interceptor.TransactionProxyFactoryBean">
    <property name="transactionManager" ref="transactionManager"/>
    <property name="target" ref="myService"/>
    <property name="transactionAttributes">
        <props>
            <prop key="save*">PROPAGATION_REQUIRED</prop>
            <prop key="delete*">PROPAGATION_REQUIRED</prop>
        </props>
    </property>
</bean>

Here:

  • A transactional proxy is created for myService, which ensures that the methods save() and delete() are executed within a transaction.

When to use?

  • If you want to use transaction management declaratively.
  • If you prefer an XML-based configuration over @Transactional annotation.

JndiObjectFactoryBean – Access to JNDI resources

When integrated into Java EE applications, some resources (such as DataSource, JMS ConnectionFactory or EJBs) are managed by an application server and accessed via JNDI (Java Naming and Directory Interface).

Instead of manually writing JNDI lookup code, you can use JndiObjectFactoryBean.

Example: Looking up a DataSource via JNDI

<bean id="dataSource" class="org.springframework.jndi.JndiObjectFactoryBean">
    <property name="jndiName" value="java:comp/env/jdbc/MyDataSource"/>
</bean>

Here:

  • The JndiObjectFactoryBean retrieves the DataSource object from JNDI and makes it available as a Spring bean.

When to use?

  • If you are working in Java EE environments where the resources are managed by an application server.
  • When you need to retrieve EJBs, JMS resources or DataSources dynamically.

LocalSessionFactoryBean – Configure Hibernate

Spring’s LocalSessionFactoryBean simplifies the setup of Hibernate’s SessionFactory.

Example: Hibernate configuration

<bean id="sessionFactory" class="org.springframework.orm.hibernate5.LocalSessionFactoryBean">
    <property name="dataSource" ref="dataSource"/>
    <property name="packagesToScan" value="com.example.model"/>
    <property name="hibernateProperties">
        <props>
            <prop key="hibernate.dialect">org.hibernate.dialect.MySQLDialect</prop>
            <prop key="hibernate.show_sql">true</prop>
        </props>
    </property>
</bean>

Here:

  • The LocalSessionFactoryBean creates and configures a Hibernate SessionFactory.
  • It automatically applies Hibernate properties and scans entity classes.

When to use?

  • When you set up Hibernate within a Spring application.
  • When you want Spring to manage the Hibernate configuration dynamically.

SqlSessionFactoryBean – Configure MyBatis

MyBatis, a popular ORM framework, uses SqlSessionFactoryBean for session management.

Example: MyBatis configuration

<bean id="sqlSessionFactory" class="org.mybatis.spring.SqlSessionFactoryBean">
    <property name="dataSource" ref="dataSource"/>
    <property name="mapperLocations" value="classpath:mappers/*.xml"/>
</bean>

Here:

  • SqlSessionFactoryBean initializes MyBatis with a configured DataSource.
  • The mapper XML files are loaded automatically.

When to use?

  • When working with the MyBatis ORM framework in a Spring application.

ServiceLocatorFactoryBean – Creating service locators

the ServiceLocatorFactoryBean helps to create service locator interfaces dynamically, reducing the need for manual lookup logic.

Example: Service Locator Interface

public interface PaymentServiceLocator {
 PaymentService getPaymentService(String serviceType);
}

Example: Registering the ServiceLocatorFactoryBean

<bean id="paymentServiceLocator" class="org.springframework.beans.factory.config.ServiceLocatorFactoryBean">
    <property name="serviceLocatorInterface" value="com.example.PaymentServiceLocator"/>
</bean>

Here:

  • Spring automatically creates an implementation of PaymentServiceLocator which delegates calls to Spring-managed beans.

When to use?

  • When implementing the Service Locator Pattern to dynamically manage multiple service implementations.

Configuring FactoryBeans in XML and Java Config

Now that we understand what FactoryBean is and have learned about the built-in implementations, it’s time to see how to configure and use a FactoryBean in Spring, both with XML-based configuration and Java-based configuration.

Spring allows you to define FactoryBeans in different ways, and the choice between XML and Java configuration depends on your project preferences and requirements.

XML-based configuration of FactoryBean

In the XML configuration we can define a FactoryBean as a regular bean and retrieve the object it creates.

Example 1: Configuring a custom FactoryBean in XML

Let’s assume we have a CarFactoryBean that produces Car objects.

import org.springframework.beans.factory.FactoryBean;

public class CarFactoryBean implements FactoryBean {
 private String model;
 private String manufacturer;

 public void setModel(String model) {
 this.model = model;
 }

 public void setManufacturer(String manufacturer) {
 this.manufacturer = manufacturer;
 }

 @Override
 public Car getObject() {
 return new Car(manufacturer, model);
 }

 @Override
 public Class getObjectType() {
 return Car.class;
 }

 @Override
 public boolean isSingleton() {
 return true;
 }
}

XML configuration for FactoryBean

<bean id="carFactory" class="com.example.CarFactoryBean">
    <property name="manufacturer" value="Tesla"/>
    <property name="model" value="Model S"/>
</bean>

<bean id="car" factory-bean="carFactory" factory-method="getObject"/>

Here:

  • autoFactory” is the FactoryBean itself.
  • auto” is the current car instance that was created using carFactory.getObject().

Access to the FactoryBean itself in XML

By default, when we call getBean("carFactory"), Spring returns the created Car object, not the CarFactoryBean.

However, if we need to retrieve the FactoryBean itself, we prefix the bean name with &.

Example: Retrieving the FactoryBean instead of the produced object

CarFactoryBean factory = (CarFactoryBean) context.getBean("&carFactory");

The &carFactory gets the actual FactoryBean, not the Car object that it creates.

Java-based configuration of the FactoryBean

For projects that use Java-based configuration (@Configuration + @Bean) instead of XML, we can define FactoryBean instances with @Bean methods.

Example 1: Defining a custom FactoryBean in the Java configuration

import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;

@Configuration public class AppConfig {

 @Bean
 public CarFactoryBean carFactoryBean() {
 CarFactoryBean factoryBean = new CarFactoryBean();
 factoryBean.setManufacturer("Tesla");
 factoryBean.setModel("Model X");
 return factoryBean;
 }

 @Bean
 public Car car(CarFactoryBean factoryBean) throws Exception {
 return factoryBean.getObject(); // Get the current Car object
 }
}

Here:

  • carFactoryBean() registers the CarFactoryBean.
  • auto()” calls “getObject()” to get the instance “Car”.

Example 2: Accessing FactoryBean in Java Config

CarFactoryBean factoryBean = (CarFactoryBean) context.getBean("&carFactoryBean");

The prefix & enables access to the FactoryBean itself.

Use FactoryBean with @Autowired

If we need to inject a FactoryBean instead of the created object, we use @Autowired with @Qualifier("&beanName").

Example: Injecting a FactoryBean in Java Config

@Component public class FactoryBeanConsumer {

 private final CarFactoryBean carFactoryBean;

 @Autowired
 public FactoryBeanConsumer(@Qualifier("&carFactoryBean") CarFactoryBean carFactoryBean) {
 this.carFactoryBean = carFactoryBean;
 }

 public void printFactoryDetails() {
 System.out.println("FactoryBean Class: " + carFactoryBean.getClass().getName());
 }
}

This ensures that Spring injects the instance of the FactoryBean and not the object that creates it.

FactoryBean in Spring Boot applications

In Spring Boot we usually prefer the Java-based configuration using @Bean methods. However, FactoryBean can still be used effectively.

Example: Using FactoryBean in a Spring Boot app

import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;

@Configuration public class CarFactoryConfig {

 @Bean
 public CarFactoryBean carFactoryBean() {
 return new CarFactoryBean();
 }

 @Bean
 public Car car(CarFactoryBean factoryBean) throws Exception {
 return factoryBean.getObject();
 }
}

When a Spring Boot application is executed, this configuration ensures that Spring loads the Car object created by CarFactoryBean.

FactoryBean vs. @Bean method – When should you use it?

Both the “FactoryBean” method and the “@Bean” method are used to define custom bean instantiation logic, but they serve different purposes.

FeatureFactoryBean@Bean Method
Spring IntegrationImplements FactoryBeanRegular method within the class @Configuration
Bean instantiationSpring calls getObject()Spring calls the method directly
Supports singleton/prototype?Yes, via isSingleton()Controlled via the annotation @Scope
Used for?Creating proxies, dynamic objects, complex initializationSimple object instantiation
Retrieve factory itself?Use &beanNameNot applicable

Use FactoryBean if you instantiate objects dynamically, proxy objects, create expensive resources or integrate third-party libraries.
Use @Bean when defining simple, directly instantiable beans.

Access to the FactoryBean itself

If a FactoryBean is registered in the Spring container, the call to getBean("factoryBeanName") by default returns the object created by the “FactoryBean” and not the “FactoryBean” instance itself.

In some cases, however, it may be necessary to access the actual instance of the FactoryBean instead of the object created by it. Spring offers a special option for this with the prefix & (ampersand).

Default behavior: Get the created object

Let’s assume we have a CarFactoryBean that creates a Car object.

import org.springframework.beans.factory.FactoryBean;

public class CarFactoryBean implements FactoryBean {
 @Override
 public Car getObject() {
 return new Car("Tesla", "Model S");
 }

 @Override
 public Class getObjectType() {
 return Car.class;
 }

 @Override
 public boolean isSingleton() {
 return true;
 }
}

Retrieve the produced bean (Car)

ApplicationContext context = new AnnotationConfigApplicationContext(AppConfig.class);

Car car = context.getBean("carFactoryBean", Car.class);
System.out.println(car); // Output: Car{Manufacturer='Tesla', Model='Model S'}

Spring automatically calls getObject() and returns the instance Car.

Retrieve the FactoryBean instead of the created object

If we want to retrieve the **FactoryBean itself, we use the prefix *& (ampersand)* when calling getBean().

Example: Get the FactoryBean itself

CarFactoryBean factoryBean = (CarFactoryBean) context.getBean("&carFactoryBean");
System.out.println(factoryBean.getClass().getName());
// Output: com.example.CarFactoryBean

By adding “&”, we instruct Spring to return the “FactoryBean” instead of the created object

When should you access the FactoryBean?

Although in most cases we only need the created object, there are some scenarios where accessing the “FactoryBean” itself is useful:

debugging and inspection

If you want to check the internal state, configuration or properties of the factory, you may need access to the “FactoryBean”.

CarFactoryBean factoryBean = (CarFactoryBean) context.getBean("&carFactoryBean");
System.out.println("FactoryBean Class: " + factoryBean.getClass().getName());

Changing the configuration dynamically

If the FactoryBean allows you to change its configuration, you can retrieve it and update its properties before calling getObject().

CarFactoryBean factoryBean = (CarFactoryBean) context.getBean("&carFactoryBean");
factoryBean.setManufacturer("BMW");
factoryBean.setModel("M5");

Car newCar = factoryBean.getObject();
System.out.println(newCar); // Output: Car{manufacturer='BMW', model='M5'}

This approach is useful if you are working with dynamic configurations.

Conditional bean creation

It may happen that you conditionally have to decide whether you want to call getObject() or work with the FactoryBean itself.

CarFactoryBean factoryBean = (CarFactoryBean) context.getBean("&carFactoryBean");

if (someCondition) {
    Car car = factoryBean.getObject(); // Get the Car instance
} else {
 System.out.println("Using factory settings only.");
}

Access to FactoryBean in XML configuration

If you are using an XML configuration, you can also retrieve the FactoryBean with the prefix &.

XML configuration for CarFactoryBean

<bean id="carFactoryBean" class="com.example.CarFactoryBean"/>

Retrieve CarFactoryBean in Java

CarFactoryBean factoryBean = (CarFactoryBean) context.getBean("&carFactoryBean");

The prefix “&” works in both XML and Java-based configurations

Access to FactoryBean in Java-based configuration (Spring Boot)

In Spring Boot, the process remains the same when using @Bean configurations.

Java configuration for FactoryBean

@Configuration public class AppConfig {

 @Bean
 public CarFactoryBean carFactoryBean() {
 return new CarFactoryBean();
 }
}

Retrieving the FactoryBean in Spring Boot

ApplicationContext context = new AnnotationConfigApplicationContext(AppConfig.class);

CarFactoryBean factoryBean = (CarFactoryBean) context.getBean("&carFactoryBean");
System.out.println("Retrieved FactoryBean: " + factoryBean.getClass().getName());

Works in the same way as in normal Spring applications.

Common pitfalls and best practices

Using FactoryBean in Spring can be very powerful, but it also has potential pitfalls. Developers often encounter problems related to incorrect retrieval of beans, misconfiguration of singletons and prototypes, debugging difficulties and improper lifecycle management.

In this section, we look at common mistakes developers make when using FactoryBean and the best practices to avoid them.

Common pitfalls with FactoryBean

Mistakenly retrieving the FactoryBean instead of the created object

One of the most common mistakes when using FactoryBean is retrieving the FactoryBean itself instead of the object it creates.

Incorrect usage: Retrieving the FactoryBean instead of the created object

CarFactoryBean factoryBean = (CarFactoryBean) context.getBean("carFactoryBean");
Car car= factoryBean.getObject(); // Throws ClassCastException

Why is this an error?

  • getBean("carFactoryBean") returns the instance Car, not CarFactoryBean.
  • Since CarFactoryBean implements FactoryBean, Spring automatically calls getObject().

Correct usage

Car car = context.getBean("carFactoryBean", Car.class);

This correctly retrieves the Car object created by the factory.

Retrieving the FactoryBean itself

If you really need the FactoryBean, use the prefix &:

CarFactoryBean factoryBean = (CarFactoryBean) context.getBean("&carFactoryBean");

Configure singleton vs. prototype beans incorrectly

Spring’s FactoryBean allows us to use the isSingleton() method to control whether the created object should be a singleton or a prototype`.

Mistake: The method isSingleton() was not overwritten correctly

@Override public boolean isSingleton() {
 return false; // Always creates a new object (may be unintentional)
}

Why is this a mistake?

  • If you don’t think about it carefully, you may unintentionally return a new instance every time a bean is requested, even if a singleton is expected.

Correct usage: Declare the correct singleton scope

@Override public boolean isSingleton() {
 return true; // Ensures that a single instance is returned
}

Best Practice:
-Use true for singleton beans (recommended for database connections, caches and expensive resources).

  • Use false for prototype beans (if a new instance is needed for each request).

Use FactoryBean if it is not necessary

Not every bean needs a FactoryBean. If an object can be created with a simple @Bean method or a constructor injection, FactoryBean is unnecessary.

Unnecessary use of FactoryBean

public class SimpleObjectFactoryBean implements FactoryBean {
 @Override
 public SimpleObject getObject() {
 return new SimpleObject();
 }

 @Override
 public Class getObjectType() {
 return SimpleObject.class;
 }

 @Override
 public boolean isSingleton() {
 return true;
 }
}

Why is this a mistake?

  • The class simply calls new SimpleObject() inside getObject(), which can easily be done by a @Bean method.

The right approach: Use @Bean instead

@Bean public SimpleObject simpleObject() {
 return new SimpleObject();
}

Best Practice:

  • Use FactoryBean only for complex objects that require additional configuration or cannot be instantiated directly.

Forgetting the correct implementation of getObjectType()

Spring refers to getObjectType() to determine the type of the bean during autowiring and dependency injection.

Mistake: Return of null in getObjectType()

@Override public Class getObjectType() {
 return null; // Incorrect
}

Why is this a mistake?

  • Spring is not able to determine the type of the bean, which leads to possible dependency injection errors.

Correct implementation

@Override public Class getObjectType() {
 return SimpleObject.class; // Explicit specification of the type
}

Best Practice:

  • Always return the correct class type in “getObjectType()” to improve compatibility with Spring.

Debugging problems with FactoryBean

Since FactoryBean does not behave like a normal bean, debugging can be difficult.

Troubleshooting tips:

Check bean type in Spring context

System.out.println(context.getType("carFactoryBean"));

This outputs the type of the returned bean and helps to find out whether it is the FactoryBean itself or the object created by it.

Check whether a bean is a FactoryBean

boolean isFactory = context.getBean("&carFactoryBean") instanceof FactoryBean;
System.out.println("Is FactoryBean: " + isFactory);

This allows you to determine whether a bean is actually a FactoryBean.

Use of @Lazy to delay the creation of the bean
If a FactoryBean contains expensive initialization logic, mark it as @Lazy to delay its creation.

@Bean
@Lazy public CarFactoryBean carFactoryBean() {
 return new CarFactoryBean();
}

This ensures that Spring only creates the factory when needed.

Best practices for the use of FactoryBean

To avoid common pitfalls and ensure best practices when using FactoryBean, follow these guidelines:

Use FactoryBean only when necessary

  • Use FactoryBean only when an object requires complex instantiation logic.
  • Rather use @Bean for simple objects that can be created normally.

Retrieve the FactoryBean correctly

  • Use context.getBean("factoryBeanName") to retrieve the produced object.
  • Use context.getBean("&factoryBeanName") to retrieve the FactoryBean itself.

Proper implementation of isSingleton()

  • Returns true if the created bean should be a singleton.
  • Returns false if the created bean is to be a new instance each time.

Always define getObjectType()

  • Helps Spring to determine autowiring compatibility.
  • Avoids problems with dependency injection.

Use @Lazy for expensive bean creation

  • If object creation is resource intensive, mark the FactoryBean as @Lazy to create it only when needed.

Use Spring Boot for simpler configurations

  • If you are working in a Spring Boot project, you should prefer Java-based configuration (@Bean) over XML configuration to improve maintainability.

Conclusion

In this blog post, we explored Spring’s FactoryBean, a powerful but often overlooked feature that provides fine-grained control over bean instantiation. We looked at the definition, use cases, implementation, configuration, built-in deployments, pitfalls and best practices.

Final thoughts

Spring’s FactoryBean is a powerful feature that provides extended control over bean instantiation. While most applications do not need FactoryBean in simple cases, it is essential for complex, dynamic or proxy-based object creation.

Key takeaways:

“factoryBean” enables dynamic and flexible bean creation.
It is used for AOP, ORM, third party integrations and expensive resource management.
Understanding when to use FactoryBean vs @Bean is crucial for better design.
Spring provides several built-in FactoryBean implementations to simplify common tasks.
Avoid common pitfalls and follow best practices for effective use.

Now that you have a solid understanding of FactoryBean, you can confidently use it in real Spring applications and optimize your bean management strategies!