2022. 9. 24. 15:17ㆍ자바 & Spring
싱글톤 패턴이란?
- 클래스의 인스턴스가 한개만 생성되는 것을 보장하는 디자인 패턴.
- 생성자가 여러 차례 호출되더라도 실제로 생성되는 객체는 하나이고, 최초 생성 이후에 호출된 생성자는 최초의 생성자가 생성한 객체를 리턴한다.
싱글톤 패턴은 같은 클래스의 인스턴스를 한개만 생성되게 하는 패턴이다.
말 그대로 같은 타입의 생성자가 여러차례 호출돼도 원래 생성되어있던 동일한 객체만이 리턴된다.
프로그램 내에 하나의 객체만 존재해야 할 때나, 프로그램 내에 해당 객체를 공유하며 사용해야 할 때 필요하다.
스프링 컨테이너
스프링 컨테이너(DI, IoC 컨테이너)는 객체 인스턴스를 싱글톤으로 관리해준다.
컨테이너는 @Bean이 붙은 어노테이션을 스프링 빈으로 관리한다. 이는 싱글톤으로 관리된다.
ApplicationContext ac = new AnnotationConfigApplicationContext(AppConfig.class);
MemberService memberService1 = ac.getBean("memberService", MemberService.class);
MemberService memberService2 = ac.getBean("memberService", MemberService.class);
memberService1, memberService2 는 같은 객체이다.
스프링 컨테이너 덕분에 요청이 올 때마다 이미 만들어진 객체를 공유해 효율적으로 재사용할 수 있다.
이처럼 싱글톤 인스턴스는 여러 클라이언트 코드에서 공유되기 때문에, 무상태(stateless)로 설계해야 한다.
싱글톤 설계방식 : Stateless (무상태)
- 특정 클라이언트에 의존적인 필드가 없도록 설계
- 특정 클라이언트가 값을 변경할 수 없도록 설계
- Read-Only 인 것이 좋다.
싱글톤 객체 필드에 공유되는 변수를 설정하면 큰 문제가 발생할 수 있다.
자바 싱글톤 예제
public class Singleton {
private static Singleton singleton = new Singleton();
private Singleton(){}
private Singleton getInstance(){
return s;
}
}
생성자를 private 으로 막아 Singleton 외부에서 new 로 Singleton 인스턴스를 생성하는 것을 막는다.
static 필드를 통해 모든 Singleton 객체가 공유하는 필드를 만들 수 있으며 이 필드는 getInstance() 를 통해서만 가져올 수 있디.
늘 같은 하나의 인스턴스를 반환하기 때문에 싱글톤 패턴을 만족하는 클래스이다.
스프링은 설정파일을 참고해 스프링컨테이너로 스프링 빈을 관리한다. 스프링은 어떻게 스프링 빈을 싱글톤으로 관리할까?
@Configuration 과 바이트코드 조작
스프링 컨테이너는 싱글톤 레지스트리이다. 따라서 스프링 빈이 싱글톤이 되도록 보장해준다.
코드에서 같은 클래스의 생성자를 3번 호출했다고 하자. 그럼 생성자를 3번 호출했으니, 해당클래스의 생성자가 3번 호출이 되면 싱글톤이 안 지켜지는 게 아닐까? 라는 의문이 든다.
스프링은 이 문제를 클래스의 바이트코드를 조작함으로써 해결한다.
ApplicationContext ac = new
AnnotationConfigApplicationContext(AppConfig.class);
위와 같이 AnnotationConfigApplicationConext() 인자로 넘긴 값은 스프링 빈으로 등록된다.
이 때 CGLIB 라는 바이트코드 조작 라이브러리를 사용해 AppConfig 클래스를 상속받는, 임의의 다른 클래스를 스프링 빈으로 등록한다.
AppConfig 를 상속받은 클래스가 있고 이를 AppConfig@CGLIB 라고 하자. (이름은 그냥 예시임)
AppConfig@CGLIB 라는 임의의 클래스가 스프링 빈으로 등록되고, 이 임의의 클래스가 싱글톤을 보장해준다.
-
@Bean이 붙은 메서드마다 이미 스프링 빈이 존재하면 존재하는 빈을 반환한다.
- 컨테이너에 없으면 새로 생성해서 컨테이너에 등록, 해당 객체 반환
즉 원래의 AppConfig 클래스에는 위 기능이 없지만, 빈으로 등록된 AppConfig@CGBLIB~~ 에 추가된 기능이라고 볼 수 있겠다.
@Bean 이 붙은 메서드마다 이미 존재하는 빈이라면 해당 빈을 반환하고, 없으면 새로 생성해 반환하여 싱글톤 패턴을 지키게 되는 것!
위에서는 @Configuration 이 붙은 AppConfig 설정 정보 클래스를 통해 스프링이 컨테이너를 생성, 빈을 싱글톤으로 관리해준다는 것을 알았다. 그렇다면 AppConfig 없이 @Bean 으로만 싱글톤 관리가 가능할까?
결론부터 말하자면 불가능하다.
@Bean으로 스프링 빈을 등록할 순 있지만, 싱글톤을 보장하지 않는다.
'자바 & Spring' 카테고리의 다른 글
빈 생명주기 콜백 (0) | 2022.10.26 |
---|---|
컴포넌트 스캔, 의존관계 자동 주입 (2) | 2022.09.25 |
Spring 특징과 장점 (0) | 2022.09.17 |
JUnit 단위 테스트 (0) | 2022.09.07 |
타임리프(thymeleaf) (0) | 2022.05.04 |