티스토리 뷰
● 도입
- Spring Container를 굳이 왜 사용하는 것일까?
- 그냥 new 연산자를 이용해 직접 instance를 만들어 연결시켜주면 되지 않을까?
- 아래의 예를 통해 알아보자
ex)
- 책 이름을 메모리에 저장하는 API를 구현해야 한다. 단, 이때 Service, Repository는 Spring Bean이 아니어야 한다.
- 그렇다면 아래와 같은 구조가 될 것이다.
- 이때 새로운 요구사항이 들어왔다.
- 책 이름을 더 이상 메모리에 저장하는 것이 아니라 MySQL 같은 DB에 저장해야한다.
- 이때 Repository에서 JdbcTemplate을 바로 가져올 수 있다.
- 그렇다면 아래와 같은 구조가 될 것이다.
- 이런 상황(메모리 → DB로 저장 위치 변경)이라면 BookService의 코드는 아래와 같이 변경될 것이다.
- 위의 상황과 그에 따른 코드 구현은 문제가 없다.
- 다만, 데이터 저장과 그 구현 방식은 Repository 계층의 역할인데 Repository를 변경함으로 인해 (데이터 저장과 그 구현 방식)과는 상관 없는 BookService의 내용까지 바꿔야 한다는 점이 문제이다.(위의 코드 참고)
- 위의 예에서는 BookMemoryRepository를 BookService 딱 한 곳에서만 사용하지만 만약 BookMemoryRepository를 더 많은 Service 계층에서 사용중이라면 해당 Service의 코드를 전부 변경해줘야만 한다.
결론 : Repository만 변경하고 싶은데 Service까지 변경하는게 싫다.
- 그렇다면 어떻게 해야 Repository를 다른 class로 바꾸더라도 Service의 내용을 변경하지 않을 수 있을까?
● 방안1 : interface
- Spring과 상관 없이 JAVA의 interface를 사용하는 방법이 있을 수 있다.
- BookService는 BookRepository interface를 사용하고 BookMemoryRepository가 해당 interface를 구현하는 방식이다.
- JAVA의 다형성을 이용하는 것이다.
- 만약 메모리 저장에서 DB 저장으로 바뀐다면 아래와 같이 코드를 수정하면 되는 것이다.
- interface 덕분에 BookService의 코드 수정량이 줄어든 것은 맞다.
- 하지만 여전히 BookService의 코드 자체를 수정해야하는 것은 동일하다.
- 내가 원하는 것은 BookService의 코드 자체를 단 한 글자도 수정하지 않는 것이다.
● 방안2 : 스프링 컨테이너
- 그래서 등장한 것이 바로 Spring Container 이다.
- BookService와 BookRepository가 모두 Spring bean이라면...
- Spring Container가 BookService를 대신 인스턴스화 하고 그 때 알아서 BookService에 넣어줄 BookRepository를 결정해줄 것이다.(Spring Container가 알아서 필요한 의존성들을 주입해주는 것이다.)
- 즉, Spring Container가 BookService를 인스턴스화 할 때 (BookMemoryRepository와 BookMySqlRepository) 중 어떤 것을 BookService에 넣어줄 지를 Spring Container가 선택하는 것이다.
- 이러면 BookService의 코드를 단 한 글자도 수정할 필요가 없다.
* 단, BookService, BookMemoryRepository, BookMySqlRepository 모두 Spring bean 이여야 한다.
- 그렇다면 여기서 또 한 가지 의문점이 나타난다.
- BookService, BookMemoryRepository, BookMySqlRepository를 모두 Spring bean으로 등록하면 Spring Container에서 이것들을 알아서 결합해주는 건 인정, OK, 이해했어
- 근데 어쨌든 BookService에 BookMemoryRepository와 BookMySqlRepository 중 어떤 것을 넣어줄지는 결국 BookService가 됐든 다른 뭐가 됐든 어느 곳에서는 반드시 코드로 설정해줘야 하는 것 아닌가?
- 이러면 interface를 사용할 때랑 뭐가 다른가?
- Spring Container가 내 마음을 읽어가지고 알아서 필요한 것을 그때그때마다 넣어줄리는 없고...
- 도대체 Spring Container는 무엇을 기준으로 두 개의 Repository 중 하나를 선택해 넣어주는 것일까?
- 그래서 Spring에 있는 것이 바로 @Primary Annotation이다.
@Primary : 우선권을 결정하는 Annotation → "@Primary가 붙은 Spring bean에게 우선권이 있어"
1. BookService에 BookMemoryRepository를 의존성 주입
2. BookService에 BookMySqlRepository를 의존성 주입
- 이렇게 Spring Container가 대신 결정해주는 방식을 제어의 역전(IoC, Inversion of Control)이라 한다.
- 그리고 Spring Container가 bean을 선택해 BookService에 넣어주는 과정을 의존성 주입(DI, Dependency Injection)이라고 한다.
결론 : 이런걸 할려고 Spring Container를 사용하는 것이다.
cf)
https://jangjjolkit.tistory.com/37
[Spring Boot] 의존성 주입 시 Bean이 여러개라면? (@Primary, @Qualifier)
들어가며 @Autowired는 Component Scan + @Component로 스프링 빈에 등록된 객체를 찾아서 필요한 의존관계를 설정한다. (우선적으로, 타입(Type)으로 해당 빈(Bean)을 찾는다.) 만약 @Autowired를 통한 자동 의존
jangjjolkit.tistory.com
'Backend > Spring' 카테고리의 다른 글
#22 JPA - 등장 (0) | 2023.09.05 |
---|---|
#21 Spring bean을 등록하는 방법 / Spring bean을 주입 받는 방법 (0) | 2023.09.03 |
#19 UserController & 스프링 컨테이너 with @RestController (0) | 2023.08.28 |
#18 Clean Code - Controller, Service, Repository 분리 (0) | 2023.08.24 |
#17 Clean Code (0) | 2023.08.21 |
- Total
- Today
- Yesterday
- 빅데이터
- 코테
- SpringBoot
- node.js
- jpa
- MySQL
- MongoDB
- java
- 메모리
- nosql
- 자료구조
- Phaser3
- Java8
- 알고리즘
- spring
- Advanced Stream
- Stream
- OS
- Phaser
- DART
- 빅데이터 분석기사
- db
- API
- git
- 프로세스
- SQL
- 코딩테스트
- Spring Boot
- 프로그래머스
- 운영체제
일 | 월 | 화 | 수 | 목 | 금 | 토 |
---|---|---|---|---|---|---|
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 |