빈(Bean) 이란?
Bean이란 컴포넌트 모델에서 유래한 JavaBeans에서 따온 단어이다.
컴포넌트 모델(Component Model)은 모듈화, 재사용성, 유지 보수성을 위해 발전해 온 소프트웨어 개발의 범용적인 개념인데, 자바(Java)는 이 개념을 기반으로 JavaBeans라는 개발 표준을 도입했다.
그래서 Bean이라는 용어는 Java 초기부터 '재사용 가능한 객체(Object)'를 지칭하는 용어로 자리잡았고, 이 개념이 스프링 프레임워크(Spring Framework)까지 이어지게 된 것이다. 이로 인해, 스프링 컨테이너에 의해 관리되는 객체를 Bean이라는 용어로 부르게 된 것이며 자바에서 컴포넌트(Component)란 사실상 Bean과 동일한 의미로 사용된다. 결론적으로 애플리케이션의 기능을 담당하고 있는 클래스의 오브젝트를 Bean이라고 부르면 된다.
1) 빈 클래스(Bean Class): 실제로 애플리케이션이 시작될 때 오브젝트를 만드는 데 사용되는 클래스.
2) 빈 오브젝트(Bean Object) : 실제로 애플리케이션이 시작될 때 빈 클래스에 의해 만들어져 사용되는 오브젝트.
스프링의 싱글톤 레지스트리(Singleton Registry)
Bean이란 곧 오브젝트이고 스프링(Spring)에 의해 관리된다는 것을 알아봤다.
그리고 우리 모두가 알다시피 스프링의 주요 특징으로 스프링은 수많은 Bean들을 싱글톤하게. 즉, 인스턴스가 오직 하나만 존재하도록 보장한다고 익히 들어왔다.
스프링이 아닌 자바로 구현한 싱글톤(Singleton Pattern)을 코드로 구현해 보면 일반적으로 아래의 모습과 같다.
public class A {
// 외부에서 객체 생성을 막기 위한 private 생성자
private A() {
}
public static A getInstance() {
A instance = (A) SingletonRegistry.getInstance("A");
if (instance == null) {
instance = new A();
SingletonRegistry.register("A", instance);
}
return instance;
}
}
public class SingletonRegistry {
// 생성된 인스턴스를 보관하기 위한 Map형태의 static 변수
private static Map<String, Object> registry = new HashMap<>();
private SingletonRegistry() {
}
// 인스턴스를 등록하는 static 메서드
public static void register(String key, Object instance) {
// 인스턴스가 아직 생성되지 않았다면 생성
if (!registry.containsKey(key)) {
registry.put(key, instance);
}
}
// 인스턴스를 반환하는 static 메서드
public static Object getInstance(String key) {
return registry.get(key);
}
}
디자인 패턴에서 나오는 싱글톤 패턴은 static(정적) 메소드를 이용해 단 하나의 객체만 생성하고, 최초 생성 이후에는 동일한 객체를 반환하는 방식으로 설계된다. 이렇게 보면 스프링을 사용하지 않고도 위 코드만 활용하면 문제없는거 아닌가? 싶다.
하지만 static메소드는 인스턴스를 생성하지 않고도 어디서든 쉽게 접근할 수 있다는 장점이 있는 반면, 전역적으로 사용되기 때문에 (애플리케이션 내 객체 간의 의존관계가 명확하지 않으면) 다양한 곳에서 무분별하게 사용될 수 있다는 잠재적 문제가 있다. 또한 정적 필드는 클래스 로딩 시점에 메모리에 할당되어, 외부에서 의존성 주입을 받을 수 없다는 가장 큰 문제가 있고, 이 때문에 테스트 환경을 구성하는 데 어려움이 있다.
장점만 있을 것 같은 싱글톤 패턴의 단점에 대해서는 구글링 조금만해도 수많은 자료에서 확인할 수 있다.
심지어 디자인 패턴의 저자 중 한 명인 에릭 감마(Erich Gamma)는 책을 개정할 때, 싱글톤 패턴(Singleton Pattern)을 책에서 제외하고 싶었다는 인터뷰를 하기도 했는데, 이런 히스토리를 보면 참 재밌는 것 같다.(다른 공동 저자들이 의견에 찬성하지 않아 그냥 남겨두게 됐다고..ㅋㅋ)
어쨌든 서버 애플리케이션 입장에서는 클라이언트 요청마다 매번 새로운 인스턴스를 만들면 메모리 비용이 낭비될 수 있기 때문에 딱 하나의 오브젝트만 만들고 공유해서 사용하는 경우가 분명히 필요하다. 이때 Spring의 싱글톤을 사용하면 위와 같은 문제를 해결할 수 있다.
Spring을 사용하는 많은 이유가 있지만 기본적으로 Spring 자체가 일종의 Singleton Registry(싱글톤 레지스트리)로 기능을 하는데, 이는 위 코드와 같이 private 생성자를 사용해야 하는 방법이 아닌 평범한 자바 클래스를 싱글톤으로 활용할 수 있게 해준다. 결론적으로 Singleton Registry 인 스프링 컨테이너(Spring Container)는 빈(Bean) 생성뿐만 아니라 관계 설정 등에 대한 제어권까지 가지게 되면서 우리가 객체들을 손쉽게 싱글톤 방식으로 관리할 수 있게 해준다.
'Spring' 카테고리의 다른 글
Servlet Container란? 그리고 Spring과의 관계 (0) | 2024.09.17 |
---|---|
Spring Container란 무엇인가? (2) | 2024.09.06 |
이클립스 Java Build Path와 Deployment Assembly 그리고 target (0) | 2023.05.24 |
EJB와 스프링 개론 (0) | 2021.02.23 |
Spring Container에 Bean등록(Xml) 및 사용 예시 (0) | 2019.10.15 |