What is a Spring FactoryBean and how does it differ from an ordinary bean?
answer
- Bean that makes another bean
- getObject() is what you get injected
- & to reach the factory itself
- ProxyFactoryBean / EntityManagerFactoryBean
- complex/proxy construction
basics
~20 sA 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 sFactoryBean<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 linesimport 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 instancego deeper
Should define it as a bean that produces another object and know getObject() result is what you get.
Should name the three methods and the '&' dereference, plus a real example like a proxy factory.
Should contrast with @Bean methods, mention product caching and type introspection, cite ProxyFactoryBean/JPA.
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