What does the '&' prefix do when looking up a bean, and when do you need it?
answer
- & = give me the factory, not the product
- FACTORY_BEAN_PREFIX == "&"
- & on non-factory -> BeanIsNotAFactoryException
- framework/introspection use, rare in app code
- transformedBeanName strips &
basics
~10 sPrefixing 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.
solid answer
~40 sBy default, resolving a FactoryBean's id returns its product (getObject() result). The '&' prefix — defined as BeanFactory.FACTORY_BEAN_PREFIX = "&" — dereferences to the factory object itself. So for a factory registered as id `foo`: `getBean("foo")` returns the product, `getBean("&foo")` returns the FactoryBean instance. You need it when you must call the factory's own methods, inspect it, reconfigure it, or verify it's a FactoryBean (e.g., in infrastructure/framework code, tests, or a BeanPostProcessor). Using '&' on a bean that is NOT a FactoryBean throws BeanIsNotAFactoryException. You can also inject the factory itself into another bean by referencing '&foo'. In practice application code rarely needs '&'; it's mostly for framework-level introspection.
code
java · 12 linesvar ctx = new AnnotationConfigApplicationContext(AppConfig.class);
// 'greeting' is a FactoryBean<String> registered under id "greeting"
String product = ctx.getBean("greeting", String.class); // "hello, ..."
FactoryBean<?> factory = (FactoryBean<?>) ctx.getBean("&greeting");
System.out.println(factory.getObjectType()); // class java.lang.String
// The prefix constant:
assert BeanFactory.FACTORY_BEAN_PREFIX.equals("&");
// Wrong target:
// ctx.getBean("&someRegularBean"); // throws BeanIsNotAFactoryExceptiongo deeper
Should know '&' gives you the factory instead of the product.
Should cite FACTORY_BEAN_PREFIX and a use case (introspection/tests).
Should mention BeanIsNotAFactoryException and transformedBeanName/isFactoryDereference helpers.
Should frame it as framework-level plumbing and discuss when injecting the factory itself is legitimate.
## The rule For a bean whose class implements `FactoryBean`, the container's default resolution returns the **product** (`getObject()`), not the factory. To reach the **factory object** you prefix the bean id with `&`. ```java Object product = ctx.getBean("foo"); // getObject() result Object factory = ctx.getBean("&foo"); // the FactoryBean instance itself ``` The prefix constant is `BeanFactory.FACTORY_BEAN_PREFIX`, whose value is the string `"&"`. ## Why it exists Because a FactoryBean creates two logically distinct objects (factory + product) under conceptually the same identity, you need a way to address each. The default (no prefix) favors the common case — you want the product. `&` is the escape hatch to the factory. ## When you actually need it - Framework/infrastructure code that must detect or manipulate FactoryBeans (e.g., `AbstractBeanFactory.isFactoryBean`, post-processors). - Tests asserting the factory is configured correctly. - Calling a configuration method on the factory before/after it builds the product. - Injecting the factory itself: `@Autowired @Qualifier("&foo")` or XML `ref="&foo"` (rare). ## Edge cases and errors - `&` on a non-FactoryBean id → `BeanIsNotAFactoryException`. - Multiple `&` are not meaningful; one dereference level. - `BeanFactoryUtils.transformedBeanName(name)` strips the `&` to get the canonical id; `isFactoryDereference(name)` checks for the prefix — useful when writing container-aware code. - In XML/`@Bean` you almost never write `&`; it surfaces mainly via programmatic `getBean` or when introspecting. ## Gotcha Developers debugging "why is my bean a String when I registered MyFactory?" are seeing the default product resolution; adding `&` reveals the factory. Conversely, accidental `&` where you wanted the product yields the factory type and a `ClassCastException` downstream.
- What happens if you call getBean("&x") where x is a plain bean, not a FactoryBean?The container throws BeanIsNotAFactoryException, because there is no factory to dereference for a non-FactoryBean id.
- Which constant defines the '&' prefix and what utility strips it?BeanFactory.FACTORY_BEAN_PREFIX holds "&". BeanFactoryUtils.transformedBeanName(name) strips it to the canonical id, and isFactoryDereference(name) tests for it.
saying these in an interview costs you the question
- Thinking '&' returns a new instance rather than the factory
- Believing you routinely need '&' in normal application wiring
- Not knowing '&' on a non-factory bean errors out