skip to content

FactoryBean & Indirect Bean Creation

FactoryBean<T> lets one bean produce another, which is how Spring builds proxies and awkward-to-construct objects; the '&' prefix fetches the factory itself instead of its product. Interviewers like it because confusing FactoryBean with a @Bean factory method is a common gap.

part ofSpring Frameworkoverview, primer and where to startread it →
on this pageshow

questions

5

What is a Spring FactoryBean and how does it differ from an ordinary bean?

level: juniorimportance: must knowfreq 55%

answer

  1. Bean that makes another bean
  2. getObject() is what you get injected
  3. & to reach the factory itself
  4. ProxyFactoryBean / EntityManagerFactoryBean
  5. complex/proxy construction

basics

~20 s

A FactoryBean is a bean whose job is to build another object. When you look it up or inject it by name, Spring hands you what its getObject() method returns, not the FactoryBean instance itself.

solid answer

~40 s

FactoryBean<T> (org.springframework.beans.factory) is an interface for a bean that acts as a factory for a more complex or hard-to-construct object. You register the factory as a normal bean, but when the container resolves that bean id, it returns getObject()'s result instead of the factory. This is the container's official extension point for objects whose construction isn't a simple constructor call — proxies, connection factories, MyBatis SqlSessionFactory, JPA's LocalContainerEntityManagerFactoryBean. The three interface methods are getObject() (the product), getObjectType() (the product's type for autowiring), and isSingleton() (whether the product is cached). It differs from a plain bean because the plain bean IS what gets injected, whereas a FactoryBean is a level of indirection: the factory is created, then asked to produce the real bean.

code

java · 26 lines
java
import org.springframework.beans.factory.FactoryBean;
import org.springframework.stereotype.Component;

@Component("greeting")
public class GreetingFactoryBean implements FactoryBean<String> {

    @Override
    public String getObject() {
        // complex/conditional construction lives here
        return "hello, " + System.getProperty("user.name");
    }

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

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

// Injection: @Autowired @Qualifier("greeting") String greeting;  -> the String, not the factory
// ctx.getBean("greeting")   -> String product
// ctx.getBean("&greeting")  -> the GreetingFactoryBean instance

go deeper

for a junior

Should define it as a bean that produces another object and know getObject() result is what you get.

for a middle

Should name the three methods and the '&' dereference, plus a real example like a proxy factory.

for a senior

Should contrast with @Bean methods, mention product caching and type introspection, cite ProxyFactoryBean/JPA.

for a principal

Should discuss when NOT to use it, lifecycle/post-processing differences of the product, and library-vs-app-code guidance.

## What it is `FactoryBean<T>` is an interface in `org.springframework.beans.factory`. A class that implements it is registered in the container like any other bean, but the container treats it specially: instead of injecting the factory object itself, it injects the object the factory *produces*. Think of it as a hook that says: "When someone asks for the bean named `dataSource`, don't give them me — call my `getObject()` and give them *that*." ## The interface ```java public interface FactoryBean<T> { T getObject() throws Exception; // the product Class<?> getObjectType(); // product type (may be null) default boolean isSingleton() { return true; } } ``` Since Spring 5.0 `getObjectType()` and `isSingleton()` are `default` methods; only `getObject()` must be implemented. ## Why it exists Some objects are awkward to build with a plain constructor or `@Bean` method: they need conditional logic, they are dynamic proxies, they come from a third-party builder, or their type isn't known until runtime. FactoryBean is the framework-level way to encapsulate that construction. Real examples shipped with Spring/ecosystem: - `org.springframework.aop.framework.ProxyFactoryBean` — builds AOP proxies. - `LocalContainerEntityManagerFactoryBean` — builds a JPA `EntityManagerFactory`. - MyBatis `SqlSessionFactoryBean`. - `AbstractFactoryBean<T>` — a convenient base class handling singleton caching for you. ## The indirection, concretely Given a factory registered as id `myThing` that returns a `Connection`: ```java Connection c = ctx.getBean("myThing", Connection.class); // gets getObject() result ``` The `Connection` is what you get, even though the bean *class* is your factory. To get the factory object itself you must dereference it with the `&` prefix: `ctx.getBean("&myThing")`. ## Ordinary bean vs FactoryBean - Ordinary bean: the instance the container creates is exactly what gets injected. - FactoryBean: two objects exist — the factory (managed by the container's lifecycle) and its product (created by calling `getObject()`). ## When to use / when not Use a FactoryBean when construction is genuinely complex, framework-level, or reusable as a library component that needs type introspection. For most application code, a plain `@Bean` factory method is simpler and preferred by the Spring team — you rarely need to write a FactoryBean yourself. ## Gotchas - Forgetting the product is what's injected, not the factory — leads to `ClassCastException` confusion. - The factory itself goes through the full bean lifecycle; the product does not get full dependency injection unless the factory wires it.

  • If GreetingFactoryBean is registered as bean id 'greeting', what does ctx.getBean("greeting") return versus ctx.getBean("&greeting")?
    getBean("greeting") returns the String from getObject(); getBean("&greeting") returns the GreetingFactoryBean instance itself, because '&' dereferences to the factory.
  • Is a FactoryBean the same as the BeanFactory?
    No. BeanFactory is the container/registry that holds and dispenses all beans. A FactoryBean is one individual bean that happens to produce another object. Similar names, unrelated roles.

saying these in an interview costs you the question

  • Confusing FactoryBean with BeanFactory (the container itself)
  • Saying the FactoryBean instance is what gets injected
  • Claiming you must call getObject() manually — the container does it

context

open as a page

Explain the three FactoryBean methods: getObject(), getObjectType(), and isSingleton().

level: middleimportance: must knowfreq 45%

basics

~20 s

getObject() returns the product bean. getObjectType() returns that product's class (or null if unknown) so Spring can autowire by type. isSingleton() tells Spring whether to build the product once and cache it (true) or call getObject() each time (false).

open as a page

What does the '&' prefix do when looking up a bean, and when do you need it?

level: middleimportance: should knowfreq 40%

basics

~10 s

Prefixing a bean name with '&' tells the container to return the FactoryBean itself instead of the object it produces. So getBean("foo") gives the product, and getBean("&foo") gives the factory.

open as a page

How does the container treat a FactoryBean's product regarding caching and bean lifecycle (post-processing, DI)?

level: seniorimportance: should knowfreq 28%

basics

~20 s

For a singleton FactoryBean the container calls getObject() once and caches the product. The product is NOT a fully lifecycle-managed bean: it skips @Autowired injection and init callbacks, though BeanPostProcessors' after-initialization phase is applied to it.

open as a page

What does SmartFactoryBean add over FactoryBean, and when would you choose a FactoryBean over a plain @Bean factory method?

level: principalimportance: nice to knowfreq 18%

basics

~20 s

SmartFactoryBean extends FactoryBean with isEagerInit() (create the singleton product eagerly at startup instead of lazily) and isPrototype() (mark the product as a prototype). Choose a FactoryBean over @Bean only for reusable, framework-level construction needing type introspection.

open as a page