Pebellslearn by building
0%
RoadmapsMatrixCoursesSandboxSign in
The Spring Core  ›  Capstone Project

Spring Bean Scope — How Many Copies?

Spring Bean Scope 14 minA bean's scope decides how many instances exist; singletons are the default and shared by all requests, so they must not hold changing per-user state.

Spring Bean Scope — How Many Copies?

A developer adds a field private int borrowCount; to LoanService to count one member's borrowings, and in testing it works. In production, members start seeing each other's counts. Nothing is wrong with the arithmetic. The bug is about how many LoanService objects exist, and that is what a bean's scope decides.

The rule

Singleton by default: one shared bean, so keep it stateless.

A bean's scope says how many instances the container creates and how long each lives.

Scope Instances Available in
singleton (default) One per application context, shared by everyone Any app
prototype A new one each time the bean is requested from the container Any app
request One per HTTP request Web apps
session One per HTTP session Web apps
application One per servlet context Web apps
@Component
@Scope("prototype")          // or @Scope(ConfigurableBeanFactory.SCOPE_PROTOTYPE)
public class LoanReceiptBuilder {
    private final List<String> lines = new ArrayList<>();
    public void add(String line) { lines.add(line); }
}

Because a singleton is shared by every request, and a web server handles many requests at once on different threads, a singleton must not hold per-user or per-request data in its fields. Fields that hold collaborators (a repository, the settings) are fine because they never change after startup. That was the borrowCount bug: one field, one object, every member writing to it.

Almost every bean you write — controllers, services, repositories — should be a stateless singleton. Keep changing data in local variables, method parameters, or the database.

The shortcut

For every field in a bean, ask: "Does this value change while the app runs?"

  • No (injected collaborators, settings): safe in a singleton.
  • Yes: move it into a local variable or the database, or, rarely, give the bean a narrower scope.
Fixing the shared borrowCountStep 1 of 4
  1. Find the field

    LoanService has private int borrowCount;, updated on every borrow.

A second trap: injecting a prototype bean into a singleton. The singleton is built once, so it receives one prototype instance at startup and keeps it forever: you get a shared object after all. When you truly need a fresh instance per use, inject an ObjectProvider<LoanReceiptBuilder> and call getObject() each time.

Drills

Answer fast — trust the rule.

quick drill

What is the default scope of a Spring bean?

quick drill

Which LoanService field is safe in a singleton?

quick drill

Which scope creates a new instance every time the bean is requested from the container?

quick drill

A singleton LoanService injects a prototype LoanReceiptBuilder in its constructor. How many builders does LoanService use across 1,000 borrow calls?

quick drill

Which scope gives each HTTP request its own instance?

Remember

  • Singleton by default: one shared bean, so keep it stateless.
  • For each field, ask "does it change at runtime?" If yes, it does not belong in a singleton.
  • Trap: a prototype injected into a singleton is created only once — use ObjectProvider for a fresh one.

Practice — level up

0/1 solved

Write your answer, then compare it with a rubric and a model answer.

ExplainFind the shared-state bug

BookController has a field private Long lastViewedBookId; that it sets on every GET /books/{id} and uses to show 'recently viewed'. Members report seeing books they never opened. Explain the bug using bean scope and propose a fix.