일 | 월 | 화 | 수 | 목 | 금 | 토 |
---|---|---|---|---|---|---|
1 | 2 | |||||
3 | 4 | 5 | 6 | 7 | 8 | 9 |
10 | 11 | 12 | 13 | 14 | 15 | 16 |
17 | 18 | 19 | 20 | 21 | 22 | 23 |
24 | 25 | 26 | 27 | 28 | 29 | 30 |
- intelij spring config
- 쉘 스크립트
- 알고리즘
- 커밋 되돌리기
- 은행원알고리즘
- Git
- 백준
- 리눅스
- @SubscribeMapping
- @Autowired
- 기본키 전략
- allocationSize
- compgen
- 티스토리챌린지
- m:n
- BindingResult
- 쿠키
- 편향된 지수
- 컴파일 타임 상수
- JDBC
- spring
- API
- 런타임 상수
- 프로그래머스
- 오블완
- DTO
- 무한정 대기
- JPA
- application layer
- 파이썬
- Today
- Total
둘셋 개발!
[spring] 싱글톤 컨테이너 본문
우선 싱글톤 컨테이너를 알아보기 전에 싱글톤이 무엇인지 살펴보자
싱글톤 패턴
: 클래스의 인스턴스가 딱 1개만 생성되는 것을 보장하는 디자인 패턴이다
순수한 DI컨테이너의 경우 요청을 할 때마다 객체를 생성하기 때문에 메모리 낭비가 발생하는 등의 문제가 발생한다.
다음은 싱글톤 패턴을 쓴 예시코드이다.
public class SingletonService {
//1. static 영역에 객체를 딱 1개만 생성해둔다.
private static final SingletonService instance = new SingletonService();
//2. public으로 열어서 객체 인스터스가 필요하면 이 static 메서드를 통해서만 조회하도록 허용한다.
public static SingletonService getInstance() {
return instance;
}
//3. 생성자를 private으로 선언해서 외부에서 new 키워드를 사용한 객체 생성을 못하게 막는다.
private SingletonService() {
}
public void logic() {
System.out.println("싱글톤 객체 로직 호출");
}
}
하지만 싱글톤 패턴만 사용하기에는 단점이 많다...
-싱글톤 패턴 문제점
- 싱글톤 패턴을 구현하는 코드 자체가 많이 들어간다.
- 의존관계 상 클라이언트가 구체 클래스에 의존한다(DIP 위반)
- 클라이언트가 구체 클래스에 의존해서 OCP원칙을 위반할 가능성이 높다.
- ...등등
스프링 컨테이너(싱글톤 컨테이너)는 이러한 싱글톤 패턴의 문제점을 해결하면서 싱글톤으로 관리할 수 있도록 관리해준다!!
싱글톤 컨테이너
스프링 컨테이너는 싱글톤 패턴을 적용하지 않아도, 객체 인스턴스를 싱글톤으로 관리해준다.
다음은 스프링 컨테이너 적용 전과 적용 후를 그림으로 나타낸 것이다.
- 순수한 DI컨테이너
- 스프링 컨테이너
스프링 컨테이너가 싱글톤을 보장하는 방법
@Configuration을 적용한 클래스를 스프링 빈에 등록할 때 스프링이 CGLIB라는 바이트 코드 조작 라이브러리를 사용해서 내가 만든 클래스를 상속받은 임의의 다른 클래스를 만들고, 그 클래스를 스프링 빈으로 등록한 것이다.
예를 들어 AppConfig클래스에 @Configuration을 적용했을 때의 스프링 컨테이너의 모습이다
➡️ 스프링 컨테이너에 빈이름은 appConfig이고 객체 인스턴트는 AppConfig를 상속한 AppConfig@CGLIB가 들어가 있다.
왜 스프링은 내가 등록한 클래스를 상속한 클래스를 만들고 빈으로 등록시키는 걸까?
AppConfig@CGLIB의 예상코드를 보면 이해가 갈 것이다.
@Configuration
public class AppConfig {
@Bean
public MemberRepository memberRepository() {
return new MemoryMemberRepository();
}
}
- AppConfig@CGLIB의 예상코드
@Bean
public MemberRepository memberRepository() {
if (memoryMemberRepository가 이미 스프링 컨테이너에 등록되어 있으면?) {
return 스프링 컨테이너에서 찾아서 반환;
} else { //스프링 컨테이너에 없으면
기존 로직을 호출해서 MemoryMemberRepository를 생성하고 스프링 컨테이너에 등록
return 반환
}
}
✔️@Bean이 붙은 메서드마다 이미 스프링 빈이 존재하면 존재한 빈을 반환하고, 없으면 빈을 생성하고 등록하고 반환한다.
(참고 : 인프런 김영한 강사님 - 스프링 핵심원리 - 기본편 )
'SPRING > spring 기본' 카테고리의 다른 글
[spring] 빈 생명주기 콜백 (0) | 2022.03.14 |
---|---|
[spring] 의존관계 주입 (0) | 2022.03.13 |
[spring] 컴포넌트 스캔 (0) | 2022.03.13 |
[spring] 스프링 컨테이너와 스프링 빈 (0) | 2022.03.09 |