티스토리 뷰

● 도입

- Spring Container를 굳이 사용하는 것일까?

- 그냥 new 연산자를 이용해 직접 instance를 만들어 연결시켜주면 되지 않을까?

- 아래의 예를 통해 알아보자

ex)

- 책 이름을 메모리에 저장하는 API를 구현해야 한다. 단, 이때 Service, Repository는 Spring Bean이 아니어야 한다.

- 그렇다면 아래와 같은 구조가 될 것이다.

인프런 - 자바와 스프링 부트로 생애 최초 서버 만들기, 누구나 쉽게 개발부터 배포까지!(최태현)

- 이때 새로운 요구사항이 들어왔다.

- 책 이름을 더 이상 메모리에 저장하는 것이 아니라 MySQL 같은 DB에 저장해야한다.

- 이때 Repository에서 JdbcTemplate을 바로 가져올 수 있다.

- 그렇다면 아래와 같은 구조가 될 것이다.

인프런 - 자바와 스프링 부트로 생애 최초 서버 만들기, 누구나 쉽게 개발부터 배포까지!(최태현)

- 이런 상황(메모리 → DB로 저장 위치 변경)이라면 BookService의 코드는 아래와 같이 변경될 것이다.

BookService class의 코드 / 인프런 - 자바와 스프링 부트로 생애 최초 서버 만들기, 누구나 쉽게 개발부터 배포까지!(최태현)

- 위의 상황과 그에 따른 코드 구현은 문제가 없다.

- 다만, 데이터 저장과 그 구현 방식은 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

공지사항
최근에 올라온 글
최근에 달린 댓글
Total
Today
Yesterday
링크
«   2025/04   »
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
글 보관함