싱글톤 레지스트리와 오브젝트 스코프

정훈희·2022년 10월 14일
0

Spring

목록 보기
5/24
post-thumbnail

싱글톤 레지스트리와 오브젝트 스코프

참조

  • 토비의 스프링 3.1 vol.1 102p~111p

오브젝트의 동일성(identity)과 동등성(equality)

두 오브젝트가 동일하다는 것은 사실은 하나의 오브젝트만 존재하는 것이고 두 개의 오브젝트 레퍼런스 변수를 갖고 있을 뿐이다.

두 오브젝트가 동등하다는 것은 두 오브젝트가 동일한 정보를 담고있는 오브젝트라는 것이다.

참고로 최상위 클래스인 Object 클래스의 equals() 메소드는 두 오브젝트의 동일성을 비교해서 결과를 알려준다.

이전에 만든 DaoFactory의 userDao()를 여러 번 호출하면 동일하지 않은 오브젝트가 생성된다.

하지만 스프링의 애플리케이션 컨텍스트에 DaoFactory를 설정 정보로 등록하고 getBean() 메소드를 이용해 userDao라는 이름으로 등록된 오브젝트를 가져오면 항상 동일한 오브젝트가 생성된다.

애플리케이션 컨텍스트는 싱글톤을 저장하고 관리하는 싱글톤 레지스트리이기도 하다.

스프링은 기본적으로 별다른 설정을 하지 않으면 내부에서 생성하는 빈 오브젝트를 모두 싱글톤으로 만든다.


싱글톤 패턴이란?

싱글톤 패턴은 어떤 클래스를 애플리케이션 내에서 제한된 인스턴스 개수(주로 하나)만 존재하도록 강제하는 패턴이다. 이렇게 하나만 만들어지는 클래스의 오브젝트는 애플리케이션 내에서 전역적으로 접근이 가능하다. 단일 오브젝트만 존재해야 하고, 이를 애플리케이션의 여러 곳에서 공유하는 경우에 주로 사용한다.

자바로 UserDao를 싱글톤으로 구현한 에시

public class UserDao {
	private static UserDao INSTANCE;
	private UserDao(ConnectionMaker connectionMaker) {
		this.connectionMaker =connectionMaker;
	}
	public static synchronized UserDao getlnstance() {
		if (INSTANCE == null) INSTANCE = new UserDao(???);
		return INSTANCE;
	}
	// ...
}

자바에서는 보통 이렇게 싱글톤을 구현한다.

  • 클래스 밖에서는 오브젝트를 생성하지 못하도록 생성자를 private로 만든다.
  • 싱글톤 오브젝트를 저장할 수 있는 자신과 같은 타입의 스태틱 필드를 정의한다.
    private static UserDao INSTANCE;
  • 스태틱 팩토리 메소드인 getlnstance( )를 만들고 이 메소드가 최초로 호출되는 시점에서 한 번만 오브젝트가 만들어지게 한다. 생성된 오브젝트는 스태틱 필드에 저장된다. 또는 스태틱 필드의 초기값으로 오브젝트를 미리 만들어둘 수도 있다.
  • 한번 싱글톤 오브젝트가 만들어지고 난 후에는 getInstance() 메소드를 통해 이미 만들어져 스태틱 필드에 저장해둔 오브젝트를 넘겨준다
    // synchronized = 현재 데이터를 사용하고 있는 쓰레드를 제외하고 나머진 접근 X
    public static synchronized UserDao getlnstance() {
    	// 인스턴스가 없으면 스태틱 필드에 저장
    	if (INSTANCE == null) INSTANCE = new UserDao(???);
    	// 이미 만들어서 스태틱 필드에 저장해둔 오브젝트 반환
    	return INSTANCE;
    }

싱글톤 패턴의 한계

  • private 생성자를 갖고 있기 때문에 상속할 수 없다.
  • 싱글톤은 테스트하기가 힘들다.
  • 서버환경에서는 싱글톤이 하나만 만들어지는 것을 보장하지 못한다.
  • 싱글톤의 사용은 전역상태를 만들 수 있기 때문에 바람직하지 못하다.

싱글톤 레지스트리

스프링은 직접 싱글톤 형태의 오브젝트를 만들고 관리하는기능을 제공하는데, 그것이 바로 싱글톤 레지스트리다. 싱글톤 레지스트리의 장점은 평범한 자바의 클래스를 싱글톤으로 활용하게 해준다는 점이다.

평범한 자바 클래스라도 IoC방식의 컨테이너를 사용해서 생성과 관계설정, 사용 등에 대한 제어권을 컨테이너에게 넘기면 쉽게 싱글톤 방식으로 만들어져 관리되게 할 수 있다.

스프링의 싱글톤 레지스트리 덕분에 싱글톤 방식으로 사용될 애플리케이션 클래스라도 public 생성자를 가질 수 있다. 따라서 테스트도 자유롭게 가능하다.

가장 중요한 것은 싱글톤 패턴과 달리 객체지향적인 설계 방식과 원칙, 디자인 패턴등을 적용하는데 아무런 제약이 없다는 점이다.

스프링은 IoC 컨테이너이자 싱글톤 레지스트리이다.

싱글톤과 오브젝트의 상태

싱글톤은 멀티스레드 환경이라면 여러 스레드가 동시접근할수 있으므로 상태관리에 주의를 기울여야 한다. 기본적으로 상태정보를 내부에 갖고 있지 않은 무상태 방식으로 만들어져야 한다.

그렇다면 어떻게 무상태 방식으로 만들 수 있을까? 바로 파라미터, 로컬 변수, 리턴 값 등을 이용하면 된다. 메소드 파라미터나 메소드 속의 로컬변수는 싱글톤이라 해도 여러 스레드가 변수의 값을 덮어쓸 일은 없다.

스프링 빈의 스코프

스프링이 관리하는 오브젝트, 즉 빈이 생성되고 존재하고, 적용되는 범위를 빈의 스코프(Scope)라고 한다. 스프링 빈의 기본 스코프는 싱글톤 스코프인데, 싱글톤 스코프는 컨테이너 내에 한 개의 오브젝트만 만들어져서 계속 유지된다.

profile
DB를 사랑하는 백엔드 개발자입니다. 열심히 공부하고 열심히 기록합니다.

0개의 댓글