Spring 기초/Spring 기초 지식

가볍게 알아보는 디자인 패턴 - 싱글톤 패턴(Singleton Pattern)

Stark97 2023. 12. 11. 02:02
반응형
 
 

스프링에 적용된 싱글톤 패턴에 대해서 간단히 알아보자

 

1. 싱글톤 패턴의 구조 이해하기

스프링 컨테이너
스프링 컨테이너

 

1-1. 스프링 컨테이너 이해하기

  • 스프링 컨테이너는 ApplicationContext를 통해 정의된다. 이 컨테이너는 IoC(Inversion of Control) 또는 DI(Dependency Injection) 컨테이너로도 알려져 있다. 주요 역할은 애플리케이션 내의 빈(Bean)들을 인스턴스화, 구성, 관리하는 것이다. 이 과정을 통해 개발자는 객체의 생성과 생명주기에 대해 걱정할 필요 없이 비즈니스 로직에 집중할 수 있다.

1-2. IoC 컨테이너 (스프링 컨테이너)의 중요성

  • IoC 컨테이너는 객체의 생성과 의존성 주입을 담당한다. 이는 객체 간의 의존성을 느슨하게 만들어, 코드의 재사용성과 테스트 용이성을 향상시킨다. 개발자는 객체의 생성과 의존성 관리를 컨테이너에 위임함으로써, 보다 선언적인 방식으로 애플리케이션을 개발할 수 있다.

 

 

 

Ioc Container는 어떤 기능을 가지고있을까?




2. ApplicationContext (Ioc Container)의 주요 기능

2-1. Singleton Bean의 생성 및 관리

  • ApplicationContext는 스프링 빈을 싱글톤으로 관리하여 메모리 사용을 최적화한다. 애플리케이션 전역에서 단 하나의 빈 인스턴스만 유지되므로, 자원 사용이 효율적이다. 이는 특히 대규모 애플리케이션에서 중요한 자원 절약이 될 수 있다.

 

2-2. Singleton과 의존성 주입(DI)

  • ApplicationContext는 싱글톤 빈 간의 의존성을 자동으로 관리한다. DI(Dependency Injection)를 통해 객체 간의 결합도를 낮추고, 개발자가 비즈니스 로직에 더 집중할 수 있도록 지원한다. 이는 코드의 유지보수성과 확장성을 높이는 데 기여한다.

 

2-3. 실용적인 응용

  • 실제 개발에서 ApplicationContext를 통한 싱글톤 관리는 다양한 서비스나 컴포넌트의 일관된 상태 유지에 중요하다. 특히, 상태를 공유하지 않는 서비스나 DAO와 같은 객체들에 대해 싱글톤 패턴을 적용하면, 메모리와 성능 면에서 이점을 얻을 수 있다.
  • ApplicationContext의 DI 기능을 활용하면, 의존성을 외부에서 주입하여 객체의 재사용성과 테스트 용이성을 높일 수 있다. 또한, 구성 변경이나 코드 리팩토링 시 의존성을 쉽게 조정할 수 있다.

 

2-4. 결론

  • ApplicationContext와 싱글톤 패턴은 스프링의 강력함과 유연성을 제공하는 핵심 요소다. 효율적인 객체 관리 및 의존성 주입을 통해, 개발자는 보다 효과적으로 애플리케이션을 구축하고 유지할 수 있다.

 

 

 

싱글톤 패턴을 알아보자



3. 싱글톤 패턴의 이해

3-1. 싱글톤 패턴

  • 싱글톤 패턴은 스프링 프레임워크에서 중요한 역할을 하는 디자인 패턴으로, 스프링 컨테이너는 각 빈(Bean)을 단 하나의 인스턴스로 관리한다. 이로 인해 메모리 사용이 최적화되고, 애플리케이션 전반에 걸쳐 빈의 상태가 공유된다.

 

3-2. 빈(Bean)의 개념

  • 스프링에서 빈은 애플리케이션 내에서 사용되는 객체를 의미하며, IoC(Inversion of Control) 컨테이너에 의해 관리된다. 빈은 주로 서비스, 컨트롤러, 리포지토리 등의 역할을 수행한다.

 

3-3. 싱글톤의 정의

  • 싱글톤 패턴은 클래스의 인스턴스를 오직 하나만 생성하며, 이 인스턴스에 전역적으로 접근 가능하도록 하는 원칙을 따른다. 스프링은 이 원칙을 모든 빈에 적용한다.

 

3-4. 스프링의 싱글톤 빈 구현 방식

  • 스프링 컨테이너는 빈을 처음 참조할 때 인스턴스를 생성하고, 이후 모든 참조에 대해 같은 인스턴스를 반환한다. 이를 통해 각 빈은 애플리케이션 내에서 한 번만 생성되며, 이후 재사용된다.

 

 

 

싱글톤 패턴은 다음과 같은 장점과 한계를 가지고 있다.



4. 싱글톤 패턴의 장점과 한계

4-1. 장점

  1. 메모리 효율성
  • 싱글톤 패턴은 같은 객체의 여러 인스턴스를 생성하는 것보다 메모리를 효율적으로 사용한다. 특히, 공통적으로 사용되는 객체(예: 서비스, 컨트롤러, 유틸리티 클래스)에 이 패턴을 적용하면 메모리 낭비를 방지할 수 있다.
  2. 성능 최적화
  • 빈의 인스턴스가 한 번만 생성되므로, 초기화 비용이 감소하고 전체적인 성능이 향상된다. 이는 복잡한 초기화 과정이 필요한 객체에 특히 유리하다.
  3. 일관된 상태 유지
  • 싱글톤 객체는 애플리케이션의 생명주기 동안 일관된 상태를 유지할 수 있다. 이는 애플리케이션에서 공유되는 리소스의 관리를 용이하게 한다.

 

4-2. 한계

  1. 상태 공유 문제
  • 여러 클라이언트나 스레드에서 싱글톤 객체를 공유할 때, 상태 관리에 주의가 필요하다. 잘못된 상태 관리는 데이터 무결성 문제를 야기할 수 있다.
  2. 스코프 제한성
  • 싱글톤 객체는 애플리케이션의 전역 상태를 나타내므로, 특정 사용 사례나 특정 사용자의 상태를 반영하기 어려울 수 있다. 예를 들어, 사용자별 세션 정보를 싱글톤 객체로 관리하기는 적합하지 않다.
  3. 테스트 어려움
  • 싱글톤 객체는 전역 상태를 가지므로, 테스트 시 이전 테스트의 상태에 영향을 받을 수 있어, 테스트 과정에서 고립성을 보장하기 어렵다.

 

4-3. 실제 적용

  • 싱글톤 패턴은 효율적인 리소스 관리를 위해 널리 사용되지만, 사용 사례에 따라 적절한 패턴 선택이 중요하다. 예를 들어, 상태를 공유하지 않아야 하는 경우나 각 요청마다 독립적인 객체가 필요한 경우에는 싱글톤 대신 다른 스코프(예: 프로토타입)를 고려할 수 있다. 이러한 이해는 스프링 기반 애플리케이션의 설계와 구현에 있어서 중요한 기준을 제공한다.

 

 

 

싱글톤 패턴의 대안인 프로토타입 스코프가 뭘까?



5. 싱글톤 패턴의 대안 - 프로토타입 스코프

5-1. 프로토타입 스코프(Prototype Scope)

  • 프로토타입 스코프에서는 요청마다 새로운 객체 인스턴스가 생성된다. 이는 각 요청에 대해 독립된 객체 상태가 필요할 때 유용하다. 예를 들어, 사용자 요청마다 특정 상태를 유지해야 하는 경우나, 매번 다른 설정이 필요한 객체의 경우 프로토타입 스코프를 사용할 수 있다.

 

5-2. 프로젝트의 요구사항에 따라 적절한 스코프 선택하기

  • 프로젝트의 요구사항에 따라 적절한 스코프를 선택하는 것이 중요하다. 싱글톤은 메모리 효율성과 객체 공유의 장점을 가지지만, 모든 경우에 적합한 것은 아니다. 반면, 프로토타입 스코프는 독립적인 객체 상태가 필요한 경우 유용하지만, 객체 생성 비용이 높을 수 있다.

 

 

 

 

마지막으로 예제를 통해 싱글톤 패턴을 알아보자




6. 예제로 알아보는 싱글톤

6-1. 싱글톤 빈 예시

  • 스프링의 싱글톤 빈은 애플리케이션 내에서 단 하나의 인스턴스만을 가진다.
  • 스프링 컨테이너에서 이 서비스를 여러 번 호출해도, 로그에는 같은 인스턴스 주소가 표시된다.
@Service
public class SingletonService {
   public SingletonService() {
       System.out.println("SingletonService 생성: " + this.toString());
   }
}

 

6-2. 비싱글톤 빈 예시 (프로토타입 스코프)

  • 프로토타입 스코프를 사용하면, 서비스를 호출할 때마다 새로운 인스턴스가 생성된다.
  • 이 서비스를 여러 번 호출하면, 로그에는 매번 다른 인스턴스 주소가 표시된다.
@Scope("prototype")
@Service
public class PrototypeService {
   public PrototypeService() {
       System.out.println("PrototypeService 생성: " + this.toString());
   }
}

 

6-3. 예제코드 호출하기

1. SingletonService (싱글톤 빈) 호출 결과

  • 스프링 컨테이너는 SingletonService 클래스의 인스턴스를 단 한 번만 생성한다. 따라서 서비스를 여러 번 호출하더라도, 생성자에서 출력되는 인스턴스의 주소는 동일하다.
SingletonService 생성: com.example.SingletonService@1a2b3c4
SingletonService 생성: com.example.SingletonService@1a2b3c4
SingletonService 생성: com.example.SingletonService@1a2b3c4

 

2. PrototypeService (프로토타입 빈) 호출 결과

  • 프로토타입 스코프에서는 PrototypeService 클래스의 인스턴스가 호출될 때마다 새로 생성된다. 따라서 서비스를 여러 번 호출할 때마다 생성자에서 출력되는 인스턴스의 주소가 달라진다.
PrototypeService 생성: com.example.PrototypeService@4d5e6f7
PrototypeService 생성: com.example.PrototypeService@8g9h0i1
PrototypeService 생성: com.example.PrototypeService@2j3k4l5

 

 

 

 

싱글톤 패턴에 대해 간단히 정리해 봤다. 다음 포스트에서는 팩토리 메서드 패턴을 알아보자


 

반응형