Scope xác định vòng đời và số lượng instance của bean.
| Scope | Instance | Dùng khi |
|---|---|---|
| singleton (default) | 1 instance dùng chung toàn app | Stateless service, repository |
| prototype | Mỗi lần inject/getBean tạo instance mới | Stateful object (command, builder) |
| request | 1/HTTP request (Web) | Request-scoped data |
| session | 1/HTTP session (Web) | User session state |
@Component
@Scope("prototype")
class Report { private List<String> rows = new ArrayList<>(); }
@Service
class ReportService {
@Autowired ApplicationContext ctx;
public Report createNew() { return ctx.getBean(Report.class); }
}Gotcha lớn nhất: inject prototype bean vào singleton bean → Spring inject 1 lần lúc startup → singleton giữ cùng 1 prototype instance mãi mãi. Fix: inject qua ApplicationContext.getBean() hoặc @Lookup method.
Default singleton phù hợp cho 99% Spring bean vì stateless.
Scope defines the lifecycle and number of instances of a bean.
| Scope | Instances | Use when |
|---|---|---|
| singleton (default) | 1 shared instance for the whole app | Stateless services, repositories |
| prototype | New instance on each inject/getBean | Stateful objects (command, builder) |
| request | 1 per HTTP request (Web) | Request-scoped data |
| session | 1 per HTTP session (Web) | User session state |
@Component
@Scope("prototype")
class Report { private List<String> rows = new ArrayList<>(); }
@Service
class ReportService {
@Autowired ApplicationContext ctx;
public Report createNew() { return ctx.getBean(Report.class); }
}Biggest gotcha: injecting a prototype bean into a singleton → Spring injects it once at startup → singleton holds the same prototype instance forever. Fix: inject via ApplicationContext.getBean() or a @Lookup method.
Singleton is the right default for 99% of Spring beans because they are stateless.