[Spring] 스프링 싱글톤 컨테이너
2025. 2. 16. 07:14ㆍ코딩 도구/백엔드 개발 (Backend Development)
반응형
스프링 싱글톤 컨테이너
김영한님의 "스프링 핵심 원리 - 기본편"을 수강하고 정리했습니다.
1. 싱글톤 패턴이란?
싱글톤 패턴은 객체를 하나만 생성하고 공유하여 메모리를 절약하는 패턴이다. 주로 여러 사용자가 동시에 접근해야 하는 객체(예: 데이터베이스 커넥션 풀, 설정 정보 관리 객체)에서 사용된다.
싱글톤 패턴의 특징
- 하나의 인스턴스만 생성: 메모리 낭비를 방지하고 효율적으로 리소스를 관리한다.
- 전역적으로 접근 가능: 하나의 객체를 여러 곳에서 공유할 수 있다.
- 생성자를 private으로 제한: 직접 인스턴스를 생성할 수 없도록 방지한다.
싱글톤 패턴 구현 예제
public class SingletonService {
private static final SingletonService instance = new SingletonService();
private SingletonService() {}
public static SingletonService getInstance() {
return instance;
}
}
2. 스프링 컨테이너의 싱글톤 관리 방식
스프링은 별도로 싱글톤 패턴을 구현하지 않아도 스프링 컨테이너가 자동으로 싱글톤 객체를 관리해준다. 따라서 개발자는 객체 생성을 직접 관리할 필요 없이, 스프링 컨테이너에 의해 생성된 빈을 사용하면 된다.
스프링의 싱글톤 컨테이너 동작 방식
- 스프링 컨테이너가 빈을 생성할 때 기본적으로 싱글톤 패턴을 적용한다.
- ApplicationContext가 관리하는 스프링 빈은 기본적으로 싱글톤으로 유지된다.
- 같은 빈을 여러 번 조회해도 동일한 인스턴스를 반환한다.
싱글톤 확인 테스트
ApplicationContext ac = new AnnotationConfigApplicationContext(AppConfig.class);
MemberService memberService1 = ac.getBean("memberService", MemberService.class);
MemberService memberService2 = ac.getBean("memberService", MemberService.class);
// 동일한 인스턴스를 반환함
System.out.println(memberService1 == memberService2); // true
3. 싱글톤 패턴의 한계와 주의점
한계
- 상태를 유지하면 안 된다.
- 싱글톤 빈은 여러 사용자가 공유하므로 상태 정보를 가지면 안 된다.
- 필드에 데이터를 저장하는 경우, 여러 사용자에게 영향을 미칠 수 있다.
- 예를 들어, private int count 같은 필드가 있는 경우, 하나의 인스턴스를 여러 사용자가 공유하기 때문에 동시에 접근하면 값이 예상과 다르게 변할 가능성이 크다.
- 따라서 상태를 유지해야 하는 경우, 싱글톤 빈을 사용하지 말고 새로운 객체를 생성해서 사용하거나, 요청 범위(Request Scope)를 고려해야 한다.
- 의존관계 주입의 어려움
- 싱글톤 패턴에서는 생성자 주입을 통한 객체 설정이 어렵다.
- 일반적으로 싱글톤 객체는 한 번만 생성되므로, 이후에 특정 의존성을 변경하거나 새롭게 주입하는 것이 어렵다.
- 스프링은 DI(의존성 주입)를 활용하여 이러한 문제를 해결하는데, @Autowired를 통해 주입된 의존성이 변할 수 없다면 다른 스코프를 활용하거나, 지연 초기화를 고려해야 한다.
- 예를 들어, 프로토타입(Prototype) 스코프의 빈을 싱글톤 빈에서 사용하면 객체가 공유되지 않고 매번 새로운 인스턴스가 생성되어 유연성이 증가할 수 있다.
스프링 싱글톤의 주의할 점
- @Configuration과 바이트코드 조작 방식 이해
- @Configuration을 사용하면 스프링이 CGLIB 바이트코드 조작을 통해 싱글톤을 보장한다.
- 이를 통해 동일한 빈이 여러 번 생성되지 않고 하나의 인스턴스만 유지된다.
@Configuration이 싱글톤을 보장하는 예제
@Configuration
public class AppConfig {
@Bean
public MemberService memberService() {
return new MemberService();
}
}
내부적으로 CGLIB 기술을 사용하여 프록시 객체를 생성하여 싱글톤을 유지한다.
4. 실무에서 중요한 내용
1) 싱글톤 패턴을 직접 구현하는 것이 아니라 스프링 컨테이너 활용
- 직접 싱글톤 패턴을 구현할 필요 없이 스프링이 제공하는 컨테이너를 활용하는 것이 유지보수에 유리하다.
- @Bean을 사용하여 빈을 등록하면 스프링 컨테이너가 자동으로 관리한다.
2) @Configuration과 바이트코드 조작 방식 이해
- 스프링은 @Configuration을 사용하여 클래스를 동적으로 조작(CGLIB)한다.
- 직접 객체를 생성하는 것이 아니라 프록시 객체를 생성하여 싱글톤을 유지한다.
3) 싱글톤 패턴의 한계와 주의점 파악
- 스프링 빈은 무상태(stateless)하게 설계해야 한다.
- 필드 값을 공유하면 안 된다 → 필요한 경우 지역 변수나 요청 범위(Request Scope) 빈을 사용해야 한다.
- 멀티스레드 환경에서도 안정적인 설계가 필요하다.
5. 결론
스프링 컨테이너는 기본적으로 싱글톤 패턴을 적용하여 빈을 관리한다. 따라서 직접 싱글톤을 구현할 필요 없이 @Bean, @Configuration을 활용하면 된다. 하지만 싱글톤 빈이 상태를 유지하면 문제가 발생할 수 있으므로 무상태(stateless)한 설계를 유지하는 것이 중요하다. 또한, @Configuration이 싱글톤을 보장하는 원리를 이해하고, 바이트코드 조작을 통한 스프링의 동작 방식을 숙지하는 것이 실무에서 중요하다.
반응형
'코딩 도구 > 백엔드 개발 (Backend Development)' 카테고리의 다른 글
[Spring] 의존관계 자동 주입 (0) | 2025.02.18 |
---|---|
[Spring] 컴포넌트 스캔(Component Scan) (0) | 2025.02.17 |
[Spring] 스프링 컨테이너와 스프링 빈 (0) | 2025.02.15 |
[Spring] 스프링 싱글톤에서 상태를 유지하면 안 되는 이유 (0) | 2025.02.13 |
[Spring] 객체 지향 설계와 스프링 (SOLID) (0) | 2025.02.10 |