스프링

토비의 스프링 - 1.6 싱글톤 레지스트리와 오브젝트 스코프

초롱불 2021. 5. 20. 15:54

개요

1. DaoFactory와 애플리케이션 컨텍스트의 또다른 차이

2. 싱글톤

3. 싱글톤과 오브젝트의 상태

본문

1. DaoFactory와 애플리케이션 컨텍스트의 또다른 차이

DaoFactory와 애플리케이션 컨텍스트의 차이 중 싱글톤으로 구현되었느냐 하는 것이 있다. 설명하기에 앞서 차이를 확인할 수 있는 코드와 결과를 보도록 하겠다.

기존 DaoFactory와 애플리케이션 컨텍스트로 생성된 객체의 차이

위 캡쳐본은 기존 DaoFactory로 생성한 dao1, dao2의 객체값 출력과 애플리케이션 컨텍스트로 생성한 dao3, dao4의 객체값을 비교한 것이다. 기존 DaoFactory는 객체값이 생성할 때마다 다르고 애플리케이션 컨텍스트는 같다는 걸 알 수가 있다. 이는 스프링의 경우 객체를 싱글톤으로 만들기 때문에 그렇다. 싱글톤이란 무엇이고 왜 스프링은 싱글톤으로 객체를 생성하는 것일까.

2. 싱글톤

싱글톤으로 빈을 만드는 것은 서버 환경에서 유용하게 사용될 수 있다. 서버 환경에서는 여러 사용자가 한번에 접속하여 프로그램을 다루게 되기 때문에 접속자마다 새로운 객체를 생성해주는 것은 서버에 부하를 가져온다. 따라서 이러한 부하를 해결하기 위해서 하나의 객체만을 만들어두고 여러 사용자가 공유해서 사용할 수 있게끔 하는 방법을 싱글톤이라고 부른다. 하지만 싱글톤 패턴은 여러 문제를 야기할 수 있다. 

1. 싱글톤은 자신만이 자기 오브젝트를 만들도록 제한하기에 생성자를 private로 제한한다. 이는 상속이라는 확장을 막는 제약이 된다.

2. 싱글톤은 테스트 하기가 어렵거나 불가능하다. 다른 객체로 만드는 것을 제한하기에 따로 객체를 만들어서 테스트를 해보는 것 자체가 새로운 일이 된다.

3. 서버 환경에서 싱글톤이 하나만 만들어지는 것을 보장하지 못한다. 서버의 클래스 로더 구성에 따라 싱글톤 클래스임에도 하나 이상의 오브젝트가 만들어질 수 있다.

4. 싱글톤 사용은 전역 상태를 만들 수 있기 때문에 바람직하지 못하다. 

위와 같은 단점 때문에 자바에서 만든 싱글톤은 그다지 사용이 권장되지 않는다.

그러나 스프링에서 직접 제공하는 싱글톤 형태의 오브젝트를 관리하는 기능은 위와 같은 단점을 가지지 않는다. static 메소드와 private 생성자를 사용해야 하는 비정상적인 클래스가 아니라 평범한 자바 클래스로도 싱글톤으로 활용하게 해준다. 오브젝트 생성에 관한 권한이 애플리케이션 컨텍스트에 있기 때문이다. 이와 같이 스프링에서 제공하는 싱글톤 기능을 싱글톤 레지스트라고 부르며 이를 활용해서 서버 환경에서 효율적으로 작동할 수 있는 싱글톤의 장점을 얻을 수 있다.

3. 싱글톤과 오브젝트의 상태

다만, 싱글톤으로 생성되기에 생성된 객체의 클래스를 만들 때 주의해야 할 점이 있다. 그것은 바로 생성되는 클래스에 지속적으로 변화되는 인스턴스 필드를 만들어두면 안 된다는 것이다. 여러 사용자가 접근할 때 생성되어 있는 한 객체에 지속적으로 접근하는 형태로 프로그램이 작동하기에 싱글톤 객체의 내부에 지속적인 변화가 일어나는 인스턴스가 있다면 다른 사용자와 변화 단계가 얽혀서 원하는 대로 작동하지 않을 수 있기 때문이다. 예시 코드는 아래와 같다.

//싱글톤으로 생성되는 UserDao
public class UserDao {
	
	private ConnectionMaker connectionMaker; //초기에 설정하면 사용 중에는 바뀌지 않는 읽기전용 인스턴스 변수
	//private Connection c;
	//private User user; 
	//매번 새로운 값으로 바뀌는 정보를 담은 인스턴스 변수는 심각한 문제를 야기한다.
	//쓰레드 환경에서 여러 사용자가 이용하는 와중에 정보가 겹쳐써진다든지 하는 문제 발생.
		
	...
				
				
		
	}

각주 처리가 된 private Connection c; 와 private User user;는 변화가 일어나는 영역인데 이를 메소드 밖 클래스의 인스턴스 필드로 선언할 경우 문제가 생길 수 있다. 인스턴스 필드로 만들어도 문제가 없는 것은 ConnectionMaker connectionMaker; 처럼 싱글톤일 경우, 읽기 전용일 경우가 있다. 이 경우 대상이 수정될 일이 없기에 문제가 생기지 않는다. 이를 주의해서 코드를 작성하자.

정리

1. 스프링은 기본적으로 객체를 싱글톤으로 만든다.

2. 싱글톤은 서버 환경에서 장점이 많다.

3. 자바에서 만드는 싱글톤 패턴은 문제의 여지가 많지만 애플리케이션 컨텍스트를 통하여 싱글톤으로 작성하는 스프링은 그러한 문제를 피하여 싱글톤의 장점을 이용할 수 있다.

4. 싱글톤으로 반환될 객체의 클래스에 변화될 수 있는 인스턴스 필드를 선언하지 말자.

 

소스 깃허브

https://github.com/cholongbul/Tobyspring

 

cholongbul/Tobyspring

토비의 스프링 연습. Contribute to cholongbul/Tobyspring development by creating an account on GitHub.

github.com