A teammate writes `@Service class RequestCounter { private int count; void increment() { count++; } }` and calls it "just a singleton, Spring makes that safe." Does it?
No — Spring made the dependency safe (visible in a constructor, substitutable in a test), it never made the instance's mutable fields safe. A Spring bean is a singleton by default, meaning exactly one RequestCounter object is created and handed to every controller that asks for it, so count is one int shared by however many request threads are running concurrently. count++ is not atomic — it is a read, an add and a write, and two threads interleaving those three steps lose increments, silently, with no exception. Spring's improvement over the hand-written singleton was removing global access (getInstance()), not removing shared mutable state; a bean with a non-final, non-thread-safe field is still a singleton with everything a singleton's mutable state has always cost, and it passes every single-threaded test written against it.