How do you declare a bean as a prototype, and where is @Scope placed on component-scanned vs @Bean-method beans?
answer
- @Scope on the class (scanned) or on the @Bean method
- use SCOPE_PROTOTYPE constant, not raw string
- no @Scope = singleton (default)
- proxyMode = TARGET_CLASS / INTERFACES for scoped proxy
- @RequestScope/@SessionScope exist; no @PrototypeScope
basics
~10 sAdd @Scope("prototype") — or @Scope(ConfigurableBeanFactory.SCOPE_PROTOTYPE). Put it on the @Component class for scanned beans, or on the @Bean method in a @Configuration class for factory-defined beans.
solid answer
~40 sYou mark a bean prototype with the @Scope annotation. For a component-scanned bean, place @Scope on the class alongside @Component/@Service/etc. For a bean defined by a factory method, place @Scope on the @Bean method inside the @Configuration class. Prefer the constant ConfigurableBeanFactory.SCOPE_PROTOTYPE over the raw string "prototype" to avoid typos. Omitting @Scope means singleton — you rarely write @Scope("singleton") explicitly since it's the default. @Scope also drives web scopes ("request", "session", "application", "websocket") and supports a proxyMode attribute (ScopedProxyMode.TARGET_CLASS / INTERFACES) used to inject shorter-lived scoped beans into longer-lived ones. The scope name is what a custom Scope implementation registers under, so the mechanism is extensible.
code
java · 12 lines// Component-scanned
@Service
@Scope(ConfigurableBeanFactory.SCOPE_PROTOTYPE)
public class PaymentAttempt { }
// Factory method with a scoped proxy so a singleton can hold it
@Configuration
class Cfg {
@Bean
@Scope(value = "prototype", proxyMode = ScopedProxyMode.TARGET_CLASS)
PaymentAttempt paymentAttempt() { return new PaymentAttempt(); }
}go deeper
Know the annotation and where it goes (class vs @Bean method) and that omission = singleton.
Mention the constants and the proxyMode attribute existence.
Explain proxyMode's role and the composed @RequestScope/@SessionScope meta-annotations.
Discuss the pluggable Scope SPI: scope names are keys registered via CustomScopeConfigurer, making scope an extension point.
## The @Scope annotation `org.springframework.context.annotation.@Scope` sets a bean's scope. Its `value` (aliased as `scopeName`) is the scope name string. The two core names are `"singleton"` and `"prototype"`; web-aware contexts add `"request"`, `"session"`, `"application"`, `"websocket"`. Because raw strings are typo-prone, Spring exposes constants: - `ConfigurableBeanFactory.SCOPE_SINGLETON` = `"singleton"` - `ConfigurableBeanFactory.SCOPE_PROTOTYPE` = `"prototype"` - `WebApplicationContext.SCOPE_REQUEST` / `SCOPE_SESSION` / `SCOPE_APPLICATION` for web scopes. ## Placement **Component-scanned bean** — annotate the class: ```java @Component @Scope(ConfigurableBeanFactory.SCOPE_PROTOTYPE) public class ReportBuilder { } ``` **@Bean factory method** — annotate the method in a `@Configuration` class: ```java @Configuration public class AppConfig { @Bean @Scope(ConfigurableBeanFactory.SCOPE_PROTOTYPE) public ReportBuilder reportBuilder() { return new ReportBuilder(); } } ``` Putting `@Scope` anywhere else (e.g., on an injection point) has no effect on the bean definition. ## Singleton is implicit Omitting `@Scope` yields singleton. Writing `@Scope("singleton")` is legal but redundant; you almost never see it. ## The proxyMode attribute `@Scope` has a `proxyMode` attribute of type `ScopedProxyMode`: - `NO` (default), - `TARGET_CLASS` (CGLIB subclass proxy), - `INTERFACES` (JDK dynamic proxy), - `DEFAULT`. A scoped proxy lets you inject a shorter-lived bean (prototype/request/session) into a longer-lived singleton: the singleton actually holds a proxy that resolves the real target *per call*. This is one of several ways to fix the prototype-in-singleton mismatch (covered in a dedicated question). ## Meta-annotation shortcuts Spring ships composed annotations so you don't write `@Scope` by hand for web scopes: `@RequestScope`, `@SessionScope`, `@ApplicationScope` (each is `@Scope(...)` with `proxyMode = TARGET_CLASS` baked in). There is no `@PrototypeScope` meta-annotation — you write `@Scope(SCOPE_PROTOTYPE)` explicitly. ## XML equivalent (legacy) In XML it's `<bean id="..." class="..." scope="prototype"/>`. The annotation form is the modern default.
- Why prefer ConfigurableBeanFactory.SCOPE_PROTOTYPE over the string "prototype"?The constant is compile-time checked, so a typo becomes a build error rather than a silent fallback/failure at runtime. It also documents intent and survives IDE refactors.
saying these in an interview costs you the question
- Thinking @Scope on an injection point changes the bean's scope.
- Believing there is a @PrototypeScope meta-annotation.
- Claiming you must write @Scope("singleton") to get a singleton.