Bean scopes and lifecycle
Explain it forThe essentials plus production detail and pitfalls.
Scopes:
singleton(the default): one instance per container. It must be stateless or thread-safe.prototype: a new instance every time one is requested.- Web scopes:
request,sessionandapplication.
The lifecycle of a bean:
- Instantiate it (call the constructor).
- Inject its dependencies.
- Run
BeanPostProcessorhooks, where annotations like@Autowiredare processed. - Call init callbacks:
@PostConstruct,afterPropertiesSet()or@Bean(initMethod = ...). - Wrap it in a proxy if needed (for
@Transactional,@Asyncand other aspects). - Use it.
- On shutdown, call
@PreDestroy(not called for prototype beans).
Example
Java
@Component
public class CourseCache {
private final Map<Long, Course> cache = new ConcurrentHashMap<>(); // thread-safe
private final CourseRepository repo;
public CourseCache(CourseRepository repo) { this.repo = repo; }
@PostConstruct
void warmUp() { // runs after injection
repo.findTop20ByOrderByRatingDesc().forEach(c -> cache.put(c.getId(), c));
}
@PreDestroy
void shutdown() { cache.clear(); }
}
@Component
@Scope(ConfigurableBeanFactory.SCOPE_PROTOTYPE)
class ReportBuilder {
private final List<String> lines = new ArrayList<>();
}Common mistake
Storing per-user data in a field of a singleton @Service. Every request shares it, so users see each other's data.
Under the hood
Injecting a prototype bean into a singleton gives you one prototype instance forever, because injection happens only once. Inject an ObjectProvider<ReportBuilder> and call getObject() each time, or use a @Lookup method. @PostConstruct and @PreDestroy come from jakarta.annotation in Spring 6+.
Check yourself
What is the default Spring bean scope?
How this connects
Know these first
Where this leads
Part of Job-ready backend developer.
Was this lesson helpful?
Finished reading? Mark it complete to track your progress.