스프링 빈은 싱글톤, Tomcat 쓰레드와의 연결

  • Spring Bean은 Singleton인데, 이게 요청 10만 개도 다 처리한다는 말인가?

  • Tomcat 쓰레드와 Spring Bean은 어떻게 연결되는가?

  • BeanFactory가 Singleton이라는 말이 Bean이 Singleton이라는 뜻인가?

  • 내가 싱글톤, 프로토타입, 스레드 세이프 개념을 혼동하고 있었던 건 아닐까?

Spring Bean은 Singleton -> 하나만 만들어진다.

  • Component, Service, Repository, Controller 등은 모두 기본 스코프가 싱글톤이다.

  • 즉, ApplicationContext 가 시작될 때 한 번만 생성되고, 이후에 요청이 들어오든 말든 그 인스턴스 하나가 계속 사용된다.

Tomcat의 Thread 100개가 동시에 같은 빈을 써도 되나?

단, Bean이 무상태(Stateless)하게 설계되어 있어야 한다.

  • 같은 UserService 객체를 Thread-1, Thread-2, Thread-99가 동시에 호출하더라도

  • 내부에 상태(state)를 저장하지 않고, 메서드의 지역 변수만 사용한다면

  • 동시 접근에도 문제 없다 -> 이게 바로 Thread-safe

3️⃣ BeanFactory vs ApplicationContext vs Singleton vs Prototype

개념
의미

BeanFactory

Spring의 최상위 DI 컨테이너 인터페이스 (기본 기능 제공)

ApplicationContext

BeanFactory의 확장 (AOP, 메시지, 이벤트 등 추가)

Singleton Scope

Spring이 1개의 인스턴스만 생성하고 공유

Prototype Scope

요청마다 새로운 인스턴스 생성

BeanFactory가 Singleton이다?

❌ BeanFactory는 "객체 공장"일 뿐이고, 빈의 스코프는 Bean 정의에 따름

BeanFactory 자체가 Singleton이다는 건 틀린 말. 정확히는 Bean의 스코프가 Singleton이면, BeanFactory는 같은 인스턴스를 계속 반환한다.

🔍 정확히 말하자면:

1. Spring Bean = 실행 주체(Thread)가 아님

  • @Service, @Controller, @Repository 같은 빈은 Thread처럼 실행되는 객체가 아닙니다

  • 이들은 정적인 로직을 담고 있는 구성 요소에 불과합니다

  • 즉, 5개를 만들어도 동시에 실행되거나 병렬 처리되는 게 아닙니다

plaintext복사편집Thread 실행 = Tomcat이 담당  
빈 로직 실행 = Thread가 빈의 메서드를 호출

2. Thread는 Tomcat이 요청마다 생성/할당

  • Spring은 Thread를 직접 만들지 않습니다

  • 요청이 들어오면 Tomcat (or Jetty 등)이 Thread Pool에서 Thread를 꺼내서 DispatcherServlet을 실행

  • 이 Thread는 싱글톤 빈이든 프로토타입 빈이든 상관없이 안전하게 재사용 가능 (stateless 조건 하에)


3. 빈을 여러 개 생성한다고 해서 병렬성이 향상되지 않는 이유

예를 들어 이런 구조를 생각해봅시다:

@Service
public class TaskService {
    public void run() { ... }
}

이걸 5개 만든다고 해도…

@Bean
public TaskService taskService1() { return new TaskService(); }

@Bean
public TaskService taskService2() { return new TaskService(); }
// ...

Tomcat Thread가 어떤 TaskService를 쓸지 알아서 골라서 실행해주지 않습니다. → 우리가 직접 라운드로빈하거나, ThreadLocal로 고르게 선택해줘야 함 → 결국 불필요한 복잡성과 메모리 낭비만 생깁니다.


🧠 그러면 왜 싱글톤 설계가 굳이 선택되었나?

🔹 1. 빈은 무거운 객체가 아니다

  • Thread처럼 계속 돌아가는 게 아니고, 내부에 상태도 없음

  • 싱글톤으로 하나만 만들어도 10만 요청 처리 가능 → 가볍고 효율적

🔹 2. 트랜잭션, AOP, DI를 프레임워크가 쉽게 관리할 수 있음

  • 싱글톤이면 프록시 객체 생성, 부가 기능 삽입, DI 흐름이 단순해짐

  • 다수 빈은 AOP 구성/프록시 캐시/DI 복잡도 증가

🔹 3. 병렬성은 ThreadPool로 제어하는 게 더 효율적

  • 병렬성은 @Async, CompletableFuture, Executor, WebFlux 같은 비동기/논블로킹 처리 도구가 더 적절함


📌 비유로 쉽게 말하면

빈은 요리법 레시피고, Thread는 그걸 들고 요리하는 셰프입니다.

레시피를 5개 복사해둔다고 셰프가 5배 빨라지진 않죠. 셰프(Thread)를 잘 늘리고 관리하는 게 병렬성 향상의 포인트입니다.


✅ 정리

질문
답변

빈을 여러 개 만들면 병렬 처리에 더 유리한가?

❌ 그렇지 않음. 병렬 처리는 Thread가 담당

그럼 왜 싱글톤만 쓰는가?

효율적이고, 프레임워크 관리가 쉬우며, thread-safe하게 설계 가능

병렬 처리는 어디서 제어하는가?

Tomcat ThreadPool, 비동기 Executor, WebFlux 같은 구조에서 담당

빈을 코어 수만큼 만들면 성능이 좋아지나?

❌ 실제 실행 주체는 코어가 아닌 Thread → 빈 개수는 무관

Last updated