Enthusiasm! Enthusiasm!

의존관계 자동 주입(2) 본문

자바 스프링/스프링 핵심원리

의존관계 자동 주입(2)

열동 2023. 1. 10. 22:06

조회 빈이 2개이상일때

현재까지는 같은 타입에 대해서 스프링 빈으로 등록할 클래스에만 @Component 애노테이션을 달아 컴포넌트 스캔에서 하나만 스캔이 되도록 하였다.만약 2개 이상의 빈을 컨테이너에 등록해두면, 타입으로만 조회하기 때문에 중복검색 오류가 발생한다. 이러한 문제를 해결하는 방법을 알아보자.

 

  • @Autowired 필드명 매칭 (필드 명을 빈 이름으로 변경)

다음과 같이 필드명을 바꿔준다

-사용하고자하는 빈으로 필드명을 변경한다.

-타입 매칭의 결과가 2개 이상일때 필드 명, 파라미터 명으로 이름을 매칭한다.

 

Qualifier

-빈 이름을 변경하지 않고 @Qualifier라는 추가 구분자를 붙혀주는 방법이다.

-빈 등록시 Qualifier를 통해 지정한 이름으로 같은 타입의 빈을 구분한다.

@Component
@Qualifier("mainDiscountPolicy")
public class RateDiscountPolicy implements DiscountPolicy {}
@Component
@Qualifier("subDiscountPolicy")
public class FixDiscountPolicy implements DiscountPolicy{}

 

-생성자 자동 주입시 원하는 빈의 이름을 지정해주면 된다

@Autowired
public OrderServiceImpl(@Qualifier("mainDiscountPolicy") DiscountPolicy discountpolicy){
	this.discountPolicy = discountPolicy;
}

 

 

Primary

@Autowired시 중복되는 빈이 있을때 @Primary를 달아주면 우선적으로 조회된다.

@Component
@Primary
public class RateDiscountPolicy implements DiscountPolicy {}

@Component
public class FixDiscountPolicy implements DiscountPolicy {}

위와 같은 상황에서 RateDiscountPolicy가 우선적으로 조회된다.

 

 

애노테이션을 직접 설계

@Target({ElementType.FIELD, ElementType.METHOD, ElementType.PARAMETER, ElementType.TYPE, ElementType.ANNOTATION_TYPE})
@Retention(RetentionPolicy.RUNTIME)
@Inherited
@Documented
@Qualifier("mainDiscountPolicy")
public @interface MainDiscountPolicy {
}

-위와 같이 애노테이션 @MainDiscountPolicy를 만들어 사용할수도 있다. 

-장점은 @Qualifier의 구분자가 문자열이라 컴파일 오류를 발생시키지 못하지만 새로 만든 애노테이션은 컴파일 단계에서 오류를 잡을 수 있어 좀 더 명확하게 설계가 가능하다.(애노테이션 이름이 틀리면 오류메시지)

-하지만 기존에 있는것들을 건드리지 않고 사용하는게 가장 좋으며 Primary로 처리할 수 있으면 되도록 Primary로 처리하자!

 

  • 정리
    • Primary는 지정만 해두면 따로 추가 작업을 안해도 되지만 Qualifier는 생성자에도 추가 작업을 해줘야 하는 불편함이 있다. 따라서 다음과 같은 상황에 적절히 나누어 쓰면 좋다
    • 메인 데이터 베이스와 서브 데이터 베이스가 있고, 메인 데이터베이스를 90프로 정도 이용하고 서브 데이터베이스를 10프로 정도 이용한다 가정하면, 메인 데이터베이스를 primary로 지정해두어 편리하게 커넥션 빈을 획득하고, 서브 데이터 베이스를 쓰는 코드에만 Qualifier를 지정하여 서브 데이터 베이스 커넥션 빈을 획득하는 방식으로 설계해주면 좋다.

조회한 빈이 모두 필요할 때

조회한 빈이 모두 필요한 상황이 있을 수도 있다. 예시 상황으로 할인 서비스를 제공하는데 클라이언트가 할인의 종류(fix or rate)를 선택할 수 있다고 가정하자. 이러한 상황에서는 두개의 빈이 모두 필요하다. 이 때는 빈을 Map 또는 List에 모두 담아둔 뒤 필요한 빈을 꺼내서 사용할 수 있도록 설계하면 된다!

 

조회한 빈이 모두 필요할 때

-DiscountService에서는 Map또는 List를 사용하여 DiscountPolicy타입의 빈들을 전부 담아둔 뒤, discount메서드에서 discountCode를 통해 원하는 할인 정책을 사용할 수 있도록 설계

 

자동,수동의 올바른 실무 운영 기준

스프링이 나오고 시간이 지나면서 점점 자동을 선호하는 추세다!

-설정 정보를 기반으로 애플리케이션을 구성하는 부분과 실제 동작하는 부분을 명확하게 나누는 것이 이상적이지만, 개발자 입장에서 스프링 빈을 하나 등록할 때 @Component 만 넣어주면 끝나는 일을 @Configuration 설정 정보에 가서 @Bean 을 적고, 객체를 생성하고, 주입할 대상을 일일이 적어주는 과정은 상당히 번거롭다. 또 관리할 빈이 많아서 설정 정보가 커지면 설정 정보를 관리하는 것 자체가 부담이 된다. 그리고 결정적으로 자동 빈 등록을 사용해도 OCP, DIP를 지킬 수 있다.

 

애플리케이션은 크게 업무 로직과 기술 지원 로직으로 나눌 수 있다.

  • 업무 로직 빈: 웹을 지원하는 컨트롤러, 핵심 비즈니스 로직이 있는 서비스, 데이터 계층의 로직을 처리하는 리포지토리등이 모두 업무 로직이다. 보통 비즈니스 요구사항을 개발할 때 추가되거나 변경된다.
  • 기술 지원 빈: 기술적인 문제나 공통 관심사(AOP)를 처리할 때 주로 사용된다. 데이터베이스 연결이나, 공통 로그 처리 처럼 업무 로직을 지원하기 위한 하부 기술이나 공통 기술들이다.

-업무 로직은 숫자도 매우 많고, 한번 개발해야 하면 컨트롤러, 서비스, 리포지토리 처럼 어느정도 유사한 패턴이 있다. 이런 경우 자동 기능을 적극 사용하는 것이 좋다. 보통 문제가 발생해도 어떤 곳에서 문제가 발생했는지 명확하게 파악하기 쉽다.

 

-기술 지원 로직은 업무 로직과 비교해서 그 수가 매우 적고, 보통 애플리케이션 전반에 걸쳐서 광범위하게 영향을 미친다. 그리고 업무 로직은 문제가 발생했을 때 어디가 문제인지 명확하게 잘 드러나지만, 기술 지원 로직은 적용이 잘 되고 있는지 아닌지 조차 파악하기 어려운 경우가 많다. 그래서 이런 기술 지원 로직들은 가급적 수동 빈 등록을 사용해서 명확하게 드러내는 것이 좋다.

 

-예시코드에서 DiscountPolicy 같은 경우는 수동으로 등록해두면 유지보수를 할때 한눈에 알아보기 어렵다.

수동 등록을 하면 한눈에 알아보기 편하다.

-다음과 같이 수동으로 등록해두면 한눈에 어떤 정책이 있는지 알아보기 쉽다.

-만약 자동으로 등록한다 하더라도, 같은 패키지에 두어 그나마 알아보기 쉽게 설계해야한다!

 

정리

-편리한 자동 기능을 기본으로 사용하자

-직접 등록하는 기술 지원 객체는 수동으로 등록하자

-다형성을 적극 활용하는 비즈니스 로직은 수동 등록을 고민해보자


이전 포스팅 - 의존관계 주입(1) https://yulddong.tistory.com/14

 

의존관계 자동 주입(1)

이 포스팅은 스프링 핵심원리 - 기본편(By Inflearn 김영한님) 강의 및 강의자료를 참고하여 작성하였습니다. 의존관계 주입의 종류 생성자 주입 수정자 주입(setter 주입) 필드 주입 일반 메서드 주

yulddong.tistory.com

 

다음 포스팅-빈 생명주기 콜백 https://yulddong.tistory.com/16

 

빈 생명주기 콜백

이 포스팅은 스프링 핵심원리 - 기본편(By Inflearn 김영한님) 강의 및 강의자료를 참고하여 작성하였습니다. 객체의 생성 및 초기화 데이터베이스는 커넥션 풀이나, 네트워크 소켓처럼 애플리케이

yulddong.tistory.com


이 포스팅은 스프링 핵심원리 - 기본편(By Inflearn 김영한님) 강의 및 강의자료를 참고하여 작성하였습니다.

'자바 스프링 > 스프링 핵심원리' 카테고리의 다른 글

빈 스코프  (0) 2023.01.12
빈 생명주기 콜백  (0) 2023.01.11
의존관계 자동 주입(1)  (0) 2023.01.09
컴포넌트 스캔  (0) 2023.01.06
싱글톤 컨테이너  (0) 2023.01.05
Comments