Spring Framework Tutorial

Software Setup and Configuration (STS/Eclipse/IntelliJ)

Core Spring

Spring Annotations

Spring Data

Spring JDBC

Spring Security

Spring - FactoryBean

FactoryBean is a core concept within the Spring framework, designed to encapsulate the logic required to instantiate a particular type of object. When you have complex initialization logic that cannot be accomplished with simple property injection or constructor arguments, FactoryBean comes into play.

Key Concepts:

  1. Purpose: The main purpose of FactoryBean is to abstract the way of constructing objects. Instead of the container directly creating an object, the FactoryBean creates the object, and Spring gets the result from it.

  2. Usage: When a bean implements FactoryBean, Spring does not return the bean itself but the object returned by the getObject() method of the FactoryBean interface.

Main Methods of FactoryBean:

  1. getObject(): Returns an instance of the object that this FactoryBean creates. Depending on the isSingleton() method, this might be shared or independent.
  2. getObjectType(): Returns the type of object that the getObject() method returns.
  3. isSingleton(): Indicates if the bean is a singleton or prototype.

Example:

Suppose you have a complex Tool object, and you wish to encapsulate its creation logic:

public class ToolFactory implements FactoryBean<Tool> {

    private int factoryId;
    private int toolId;

    @Override
    public Tool getObject() throws Exception {
        // This is the place to put complex initialization logic.
        Tool tool = new Tool();
        tool.setId(toolId * factoryId);
        return tool;
    }

    @Override
    public Class<?> getObjectType() {
        return Tool.class;
    }

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

    // setters and getters for factoryId and toolId...
}

Then, in your Spring XML configuration or Java Config, you can define the ToolFactory bean:

<bean id="toolFactory" class="com.example.ToolFactory">
    <property name="factoryId" value="1234" />
    <property name="toolId" value="5678" />
</bean>

When you request a tool bean from the Spring container, it will provide you with the result of toolFactory.getObject(), which is a Tool object.

Considerations:

  • Using a FactoryBean can sometimes make the configuration look more complex, as it might not be immediately clear which type of object is being created. It's important to document and name beans clearly when using FactoryBean to aid in understanding.

  • It's worth noting that if you need to access the FactoryBean instance itself (rather than the product of the FactoryBean), you can prepend the bean's ID/name with an ampersand (&). For example: context.getBean("&toolFactory") will return the ToolFactory instance, not a Tool object.

In summary, FactoryBean provides a powerful mechanism to encapsulate the creation logic for beans within the Spring container, especially when standard bean instantiation (using constructors and setters) is insufficient.

  1. Creating custom FactoryBean in Spring:

    • A custom FactoryBean is a class that implements the FactoryBean interface to define a factory for creating and managing beans.
    public class MyObjectFactoryBean implements FactoryBean<MyObject> {
        @Override
        public MyObject getObject() throws Exception {
            // Custom logic to create and configure MyObject
            return new MyObject();
        }
    
        @Override
        public Class<?> getObjectType() {
            return MyObject.class;
        }
    }
    
  2. How to use FactoryBean for object creation in Spring:

    • Use the custom FactoryBean in your Spring configuration to create instances of the specified object.
    <bean id="myObject" class="com.example.MyObjectFactoryBean" />
    
  3. Implementing FactoryBean interface in Spring:

    • Implement the FactoryBean interface in your custom class, providing logic for creating and configuring the target object.
    public class MyObjectFactoryBean implements FactoryBean<MyObject> {
        // Implementation of getObject and getObjectType methods
    }
    
  4. FactoryBean vs regular bean creation in Spring:

    • Regular bean creation involves instantiating a bean directly, while using a FactoryBean provides a more flexible and customizable way to create and configure objects.
    // Regular bean creation
    <bean id="myObject" class="com.example.MyObject" />
    
    // FactoryBean creation
    <bean id="myObject" class="com.example.MyObjectFactoryBean" />
    
  5. Injecting dependencies with FactoryBean in Spring:

    • A FactoryBean can be configured to inject dependencies into the target object during creation.
    public class MyObjectFactoryBean implements FactoryBean<MyObject> {
        @Autowired
        private Dependency dependency;
    
        // Implementation of getObject and getObjectType methods
    }
    
  6. Configuring FactoryBean with annotations in Spring:

    • Use annotations like @Component and @Autowired to configure and inject dependencies into the custom FactoryBean.
    @Component
    public class MyObjectFactoryBean implements FactoryBean<MyObject> {
        @Autowired
        private Dependency dependency;
    
        // Implementation of getObject and getObjectType methods
    }
    
  7. Advanced use cases of FactoryBean in Spring framework:

    • FactoryBean can be used for advanced scenarios, such as conditional creation, dynamic configuration, or custom initialization.
    public class MyObjectFactoryBean implements FactoryBean<MyObject> {
        private boolean enableSpecialFeature;
    
        public void setEnableSpecialFeature(boolean enableSpecialFeature) {
            this.enableSpecialFeature = enableSpecialFeature;
        }
    
        // Implementation of getObject and getObjectType methods
    }