-
Spring Singleton vs Java static 기반 SingletonSTUDY/백엔드 2024. 11. 27. 22:41
Spring Singleton
스프링에서의 싱글톤은 Spring IoC 컨테이너가 관리하는 객체의 라이프사이클을 통해 보장된다. 스프링 컨테이너는 해당 객체의 인스턴스를 하나만 생성하고, 이를 애플리케이션 전체에서 공유한다. 스프링은 기본적으로 @Bean, @Component 등의 어노테이션을 사용하여 싱글톤을 관리하고, 이는 ApplicationContext를 통해 관리된다.
Spring Bean 등록
1. @Component
@Component public class MyService { }
Spring은 컴포넌트 스캔(Component Scan)을 사용해 @Component 어노테이션이 있는 클래스들을 찾아서 자동으로 스프링 컨테이너에 싱글톤 빈으로 등록하고 관리한다.
2. @Configuration + @Bean
@Configuration public class AppConfig { @Bean public MyService myService() { return new MyService(); } }
일반적으로 컴포넌트 스캔을 사용해 자동으로 빈을 등록하는 방법을 사용하지만, @Bean 어노테이션을 사용해 수동으로 빈을 등록해야 하는 경우도 존재한다.
수동으로 스프링 컨테이너에 빈을 등록하는 경우, 클래스에 @Configuration 어노테이션을 붙여주고, @Bean을 사용해 빈을 수동으로 등록한다. @Configuration을 사용하는 이유는 CGLIB으로 프록시를 생성해, 해당 클래스 내에서 @Bean으로 등록된 빈이 항상 동일한 인스턴스를 반환하도록 싱글톤을 보장하기 때문이다.
Spring Singleton VS Java static 기반 Singleton
특징 Java static 기반 싱글톤 Spring 싱글톤 관리 및 범위 클래스 로더에 의해 관리되며, 애플리케이션 전체 범위에서 유효 Spring IoC 컨테이너에 의해 관리되며, 스프링 컨테이너 내에서 유효 객체 생성 시점 클래스 로딩 시점에 한 번만 생성 Spring IoC 컨테이너가 초기화 될 때 한 번 생성 스레드 안전성 기본적으로 스레드 안전하지 않음 기존적으로 스레드 안전성을 보장하지만, 상태를 갖는 빈은 주의해야 함 사용 방식 getInstance() 메서드로 직접 호출 의존성 주입하거나, ApplicationContext에서 조회 성능 인스턴스를 직접 관리하므로 성능이 빠름(단, 동기화가 없으면 위험) 스프링 컨테이너를 통해 관리되므로 성능에서 오버헤드(초기화, 의존성 주입, 멀티스레드 동기화 등의 비용)가 있을 수 있음 유연성 클래스 내부에서만 인스턴스를 관리하므로 유연성이 낮음 의존성 주입으로 다양한 객체 주입 가능, 유연성 높음 사용 환경 전역적으로 하나의 인스턴스를 공유할 때 서비스, DAO 객체 등 애플리케이션 내 객체 관리 객체 관리 방식
- Java Static 기반 싱글톤: static 변수를 사용하여 클래스의 인스턴스를 하나만 생성하고, 이후에는 그 인스턴스를 재사용한다. 객체의 생명주기나 상태를 직접 관리해야 한다.
- Spring 싱글톤: Spring IoC (Inversion of Control) 컨테이너가 객체의 생명주기와 상태를 자동으로 관리하며, 기본적으로 모든 빈은 싱글톤 패턴으로 관리된다.
스레드 안전성
- Java Static 기반 싱글톤: 멀티스레드 환경에서 동기화 처리가 없으면, 여러 스레드에서 동시에 getInstance()를 호출할 경우 인스턴스가 여러 번 생성될 위험이 있다.
- Spring 싱글톤: Spring은 빈을 싱글톤으로 관리하되, 스레드 안전성을 보장할 수 있도록 설계된다. 그러나 상태를 가지는 빈의 경우 멀티스레드 환경에서 문제가 발생할 수 있어 주의해야 한다.
객체의 생명주기 관리
- Java Static 기반 싱글톤: 객체의 생명주기는 static 변수의 초기화에 의해 제어되며, 명시적으로 객체의 생성과 소멸을 관리해야 한다. 객체가 생성된 후에는 null로 설정하지 않는 한 계속 메모리에 남아있다.
- Spring 싱글톤: Spring IoC 컨테이너가 빈의 생성과 소멸을 자동으로 관리한다. 빈은 컨테이너 초기화 시 한 번만 생성되며, 컨테이너 종료 시 자동으로 소멸된다.
의존성 주입 (Dependency Injection)
- Java Static 기반 싱글톤: static 싱글톤은 일반적으로 외부에서 다른 객체를 주입하는 방식이 없으며, 의존성 주입을 구현하려면 수동으로 관리해야 한다.
- Spring 싱글톤: Spring은 @Autowired, @Inject, 생성자 주입 등을 통해 자동으로 의존성을 주입한다. 이를 통해 객체 간 결합도를 낮추고, 유연하게 의존성을 관리할 수 있다.
테스트 용이성
- Java Static 기반 싱글톤: static 기반 싱글톤은 객체의 상태를 초기화하는 것이 어렵고, 인스턴스를 재사용하므로 테스트가 어렵다. 예를 들어, getInstance() 메서드를 테스트할 때, 테스트 간에 상태가 공유되어 버그가 발생할 수 있다.
- Spring 싱글톤: @SpringBootTest와 같은 테스트 어노테이션이나, Mockito 등을 활용한 테스트가 용이하다.
'STUDY > 백엔드' 카테고리의 다른 글
Apache MPM (0) 2022.01.13 실제 Client IP 구하기 (0) 2021.06.25 Java Bean Validation (0) 2021.05.07 @Transactional (0) 2021.05.07 람다 표현식 (0) 2021.05.06