[Spring] 7-7. 빈 등록 자동, 수동의 올바른 실무 운영

송광호·2024년 1월 10일

[Spring]

목록 보기
34/41
post-thumbnail

Spring 시리즈는 혼자 공부하며 기록으로 남기고, 만약 잘못 학습 한 지식이 있다면 공유하며 피드백을 받고자 작성합니다.
스프링에 대해 깊게 공부해보고자 인프런의 김영한 강사님께서 강의를 진행하시는 (스프링 핵심 원리 - 기본편) 강의를 수강하며 정리하는 글입니다.
혹여나 글을 읽으시며 잘못 설명된 부분이 있다면 지적 부탁드리겠습니다.


실무 운영에서 수동, 자동 등록 기준

자동 기능을 기본으로 사용

  • 컴포넌트 스캔이라 자동 의존관계 주입을 기본으로 사용하는게 좋다.
  • 스프링이 나오고 시간이 갈수록 점점 자동을 선호하는 추세이다.
  • 스프링은 @Component 애노테이션 뿐만 아니라 @Repository, @Service, @Controller처럼 계층에 맞춰 일반적인 애플리케이션 로직도 자동으로 스캔할 수 있다.
  • 스프링 부트 시작 애플리케이션의 애노테이션을 타고 들어가보면 기본적으로 @ComponentScan을 깔고있다.

개발자 입장

  • 스프링 빈을 하나 등록할 때 @Component 애노테이션 하나만 넣어주면 끝날일을 @Configuration 설정 정보에 가서 @Bean을 통해 객체생성, 주입할 대상을 하나하나 적어주는 과정은 상당히 번거롭다.
  • 만약 빈이 한두개가 아니라 수십 수백개면? 이것 자체만으로도 부담이 된다.
  • 자동 빈 등록을 사용하더라도 OCP, DIP 원칙도 지킬 수 있다.

그렇다면 수동 빈등록은 언제 사용하는데?

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

업무 로직

  • 웹을 지원하는 컨트롤러, 핵심 비즈니스 로직이 있는 서비스, 데이터 계층의 로직을 처리하는 리포지토리
  • 보통 비즈니스 요구사항이 개발할 때 추가되거나 변경된다.

기술 지원 로직

  • 공통적인 관심사를 처리할 때 주로 사용된다.
  • 예를 들어 데이터베이스에 연결하는 것, 공통 로그 처리 업무 로직을 지원하기 위한 하부 기술이나 공통 기술들
  • 업무 로직은 숫자도 매우 많고 컨트롤러, 서비스, 리포지토리 처럼 어느정도 유사한 패턴을 가지고있다.
  • 이런경우 각 애노테이션들을 추가하면 컴포넌트 스캔의 대상이 되어 스프링이 실행될때 자동으로 스캔이 되므로 자동 기능을 적극 사용하는것이 좋다. 그래야 문제가 발생해도 어떤 곳에서 발생했는지 명확하게 파악이 잘 된다.
  • 기술 지원 로직은 업무 로직과 비교하면 그 수가 매우 적고, 애플리케이션 전반에 걸쳐서 광범위하게 영향을 미친다.
  • 업무 지원 로직은 문제가 발생하면 어디가 문제인지 명확히 알 수 있지만, 기술 지원 로직은 적용이 잘 되는지, 아닌지 파악하기 어려운 경우가 많다.
  • 그래서 이런 기술 지원 로직들은 가급적 수동 빈 등록을 사용해서 명확하게 알 수 있게 하는 것이 좋다.

비즈니스 로직 중에서 다형성을 적극 활용할 때

  • 앞 강의에서 작성된 전략패턴을 구현한 discountPolicy를 생각해보자
    static class DiscountService {
        private final Map<String, DiscountPolicy> policyMap;
        private final List<DiscountPolicy> policyList;

        public DiscountService(Map<String, DiscountPolicy> policyMap, List<DiscountPolicy> policyList) {
            this.policyMap = policyMap;
            this.policyList = policyList;
            System.out.println("policyMap = " + policyMap);
            System.out.println("policyList = " + policyList);
        }

        public int discount(Member member, int price, String discountCode) {
            DiscountPolicy discountPolicy = policyMap.get(discountCode);
            return discountPolicy.discount(member, price);
        }
    }
  • 구현체가 뭐가 들어오는지 한눈에 보이지가 않는다
@Configuration
 public class DiscountPolicyConfig {
 
     @Bean
     public DiscountPolicy rateDiscountPolicy() {
         return new RateDiscountPolicy();
     }
     
     @Bean
     public DiscountPolicy fixDiscountPolicy() {
         return new FixDiscountPolicy();
     }
}
  • 이런식으로 설정 정보만 봐도 한눈에 빈의 이름, 어떤 빈들이 주입되는지 파악이 가능해야한다.
  • 그럼에도 자동 등록을 사용하고싶으면 파악하기 좋게 DiscountPolicy 구현 빈들만 따로 모아서 패키지로 구성해두어야 한다.

정리

  • 편리한 자동 기능을 기본으로 활용하자
  • 직접 등록하는 기술 지원 객체는 수동 등록
  • 다형성을 적극 활용하는 비즈니스 로직은 수동 등록을 고민 해보자

0개의 댓글