TIL 2023-12-12 왜 Service를 인터페이스와 구현체로 나눌까?

2023. 12. 12. 17:09TIL
목차
  1. 의문점
  2. 인터페이스의 목적
  3. 그래서 어떻게 주입을 받을 수 있는데?
  4. @Qualifier
  5. @Primary

♥️

오늘은 기존 개인 투 두 프로젝트에서 Service를 인터페이스화 시키고 Service 구현체를 만드는 리팩토링을 진행하였다.

 


      
public interface CardService {
// ...
}

      
@Service
public class CardServiceImpl implements CardService {
// ...
}

 

의문점

굳이 인터페이스를 써야하나? 라는 의문점을 가진 것은 아니다.

 

Spring에서 의존성 관리를 위해서 @Service 어노테이션을 갖고있는 클래스의 Bean을 빈팩토리에 넣어서 가지고 있는데, 내가 CardService인터페이스를 Controller에서 주입을 받는다고 하면

 

Spring 은 자동으로 인터페이스의 구현체 Bean을 찾아서 주입을 해준다.

 

여기서 들었던 의문이다.

 


      
@Service
public class CardServiceImpl1 implements CardService {
// ...
}

      
@Service
public class CardServiceImpl2 implements CardService {
// ...
}

      
@Service
public class CardServiceImpl3 implements CardService {
// ...
}

 

 

구현체가 여러개면 Bean을 어떻게 주입해줄 건데?

 

너가 어떻게 알고 주입을 해줄 건데?

 


      
@RestController
public class CardController {
private final CardService cardService;
public CardController(CardService cardService) { // 에러 발생!
this.cardService = cardService;
}

 

CardService의 Bean이 하나 이상이여서 주입을 받을 수 없어용.

 

그러면 Impl 클래스에서만 인터페이스를 주입 받고 Controller에서는 ServiceImpl을 주입 받으면 되는 거 아니야??


      
@RestController
public class CardController {
private final CardServiceImpl1 cardService;
public CardController(CardServiceImpl1 cardService) {
this.cardService = cardService;
}

 

그냥 딱 이렇게 받아주면 되는 거 아닌가??

 

라고 생각했다.

인터페이스의 목적

인터페이스를 왜 써야하냐? 라는 의문을 가진 건 아니라고 위에서 말했지만 설명에 들어가기 전에, 인터페이스의 목적을 먼저 정리해야겠다.

 

인터페이스는 약속이다.

인터페이스는 통일성 유지다.

인터페이스는 규약이다.

 

내가 JpaRepository를 쓴다고 하면 많은 종류의 DB를 이용할 수 있다. 이 이유는 인터페이스 덕분이다.

 

DB 드라이버가 JpaRepository를 구현해서 자신의 DB와 맞도록 쿼리문을 작성해주는 것이다.

 

이게 인터페이스 덕분에 많은 종류의 DB를 이용할 수 있는 것이다.

 

어? 무궁무진하네?

 

그래서 어떻게 주입을 받을 수 있는데?

많은 블로그에서는 @Qualifier와 @Primary를 얘기한다.

 

@Qualifier


      
@Service
@Qualifier("cardService1")
public class CardServiceImpl1 implements CardService {
// ...
}
@Service
@Qualifier("cardService2")
public class CardServiceImpl2 implements CardService {
// ...
}
@Service
@Qualifier("cardService3")
public class CardServiceImpl3 implements CardService {
// ...
}

 


      
@RestController
public class CardController {
private final CardService cardService;
public CardController(@Qualifier("cardService1") CardService cardService) {
this.cardService = cardService; // CardServiceImpl1 의 Bean을 주입
}

 

인터페이스의 수많은 구현체중 어떤 구현체의 Bean을 받을 것인지 명확하게 짚어주는 것이다.

이러면 CardServiceImpl1의 Bean을 Controller에서 주입 받는다.

 

어? 버전 관리가 가능하겠네?

 

@Primary


      
@Service
public class CardServiceImpl1 implements CardService {
// ...
}
@Service
@Primary
public class CardServiceImpl2 implements CardService {
// ...
}
@Service
public class CardServiceImpl3 implements CardService {
// ...
}

 


      
@RestController
public class CardController {
private final CardService cardService;
public CardController(CardService cardService) {
this.cardService = cardService; // CardServiceImpl2 의 Bean을 주입
}

 

수많은 구현체 중 Primary가 붙은 클래스의 Bean을 자동으로 주입하라고 명확하게 표현하는 것이다.

 

뭐 비슷하네?

 

근데 여기서 더 생각이 많이 나는 게 많다

 

예를 들어..

어?? 회원 등급 별로 기능을 분리를 할 수 있겠네???

어?? Gradle이나 이런 버전관리에서도 이런 유사한 방식을 쓰겠네???

 


      
@Controller
public class CardController {
// 예시 코드
private final CardService cardService;
public CardController(CardServiceImpl1 cardService1, CardServiceImpl2 cardService2) {
if () {}
}
}

 

이런 느낌으로 뭘 주입 해줄지도 정해줄 수 있겠네?

 

 

어???????????????

 

 

AOP를 앞단에 넣고 여기서 등급이라던지 이런 분리 로직을 만들고 뭘 주입 받을 건지 고를 수 있게 할 수 있겠네??????

 

어??????? 생각보다 엄청 무궁무진하네???

라고 생각하며 배운 하루다 🤤🤤

저작자표시 (새창열림)

'TIL' 카테고리의 다른 글

TIL 2023-12-14 정적쿼리 동적쿼리 그리고 QueryDSL 약간  (0) 2023.12.14
TIL 2023-12-13 AOP Logging 구현  (0) 2023.12.13
TIL 2023-12-11 명시적 삭제 컬럼  (0) 2023.12.11
TIL 2023-12-08 getWriter() has already been called for this response  (0) 2023.12.08
TIL 2023-12-07 Refresh Token 쓰는 이유 및 DB로 Redis를 쓰는 이유  (0) 2023.12.07
  1. 의문점
  2. 인터페이스의 목적
  3. 그래서 어떻게 주입을 받을 수 있는데?
  4. @Qualifier
  5. @Primary
'TIL' 카테고리의 다른 글
  • TIL 2023-12-14 정적쿼리 동적쿼리 그리고 QueryDSL 약간
  • TIL 2023-12-13 AOP Logging 구현
  • TIL 2023-12-11 명시적 삭제 컬럼
  • TIL 2023-12-08 getWriter() has already been called for this response
wonow_
wonow_
꾸준히 성장하는 개발자 WONOW 입니다. 🤗
wonow_
wonow_
wonow_
전체
오늘
어제
  • 분류 전체보기
    • Language
      • JAVA
    • TIL
    • 코딩테스트
      • 프로그래머스
      • 백준
    • 프로젝트
      • JAVA
      • Spring
    • 기타
    • ERROR
      • Spring
    • CS
      • 알고리즘
      • DB
      • Kafka
    • 잡담
    • 활동
      • 척척박사

블로그 메뉴

  • 홈
  • 태그
  • 방명록

공지사항

인기 글

태그

  • 티스토리챌린지
  • 홀짝 구분하기
  • 티스토리 꾸미기
  • 오블완
  • 문자열 붙여서 출력하기
  • 나는바봉가봉가
  • 프로그래머스
  • 문자열 돌리기
  • 공부열심히하자

최근 댓글

최근 글

hELLO · Designed By 정상우.v4.2.1
wonow_
TIL 2023-12-12 왜 Service를 인터페이스와 구현체로 나눌까?
상단으로

티스토리툴바

단축키

내 블로그

내 블로그 - 관리자 홈 전환
Q
Q
새 글 쓰기
W
W

블로그 게시글

글 수정 (권한 있는 경우)
E
E
댓글 영역으로 이동
C
C

모든 영역

이 페이지의 URL 복사
S
S
맨 위로 이동
T
T
티스토리 홈 이동
H
H
단축키 안내
Shift + /
⇧ + /

* 단축키는 한글/영문 대소문자로 이용 가능하며, 티스토리 기본 도메인에서만 동작합니다.