본문 바로가기

WINK-(Web & App)/Spring Boot 스터디

[2024 Spring Boot 스터디] 유태근 #3 주차 - 컴포넌트 스캔과 의존관계 자동 주입

반응형

컴포넌트 스캔

  1. @Bean을 통해 설정 정보를 작성하고 직접 스프링 빈으로 등록해줄 수 있다.
  2. @ComponentScan은 @Component가 붙은 모든 클래스를 스프링 빈으로 등록한다.
  3. 스프링 컨테이너가 @Autowired를 찾아 자동으로 스프링 빈을 주입한다.

@ComponentScan

 

  • backPackages 파라미터를 통해 탐색할 패키지의 시작 위치 지정 가능
  • 최상단에 위치시켜 하위에 모든 component가 등록되게끔 구현하는 것이 보편적
  • @Component 뿐만 아니라 해당 어노테이션을 달고 있는 @Controller, @Service, @Configuration 등도 대상에 포함
  • useDefaultFilters, includeFilters, excludeFilters를 통해 컴포넌트 스캔 대상 설정 가능

의존관계 자동 주입

스프링은 스프링 컨테이너를 만들고 스프링 빈을 등록후에 의존관계를 주입한다. 단, 생성자 주입은 스프링 빈 등록시에 주입한다.

 

생성자 주입

private final MemberRepository memberRepository;
private final DiscountPolicy discountPolicy;

@Autowired	//생성자가 1개 이면 생략 가능
public OrderServiceImpl(MemberRepository memberRepository, DiscountPolicy discountPolicy) {
    this.memberRepository = memberRepository;
    this.discountPolicy = discountPolicy;
}

 

  • 생성자를 통해 의존 관계를 주입하는 방법으로 생성자 호출 시점에 1번만 호출되기 때문에 주로 불변이면서 필수

수정자 주입

private final MemberRepository memberRepository;
private final DiscountPolicy discountPolicy;

@Autowired
public void setMemberRepository(MemberRepository memberRepository) {
    this.memberRepository = memberRepository;
}

@Autowired
public void setDiscountPolicy(DiscountPolicy discountPolicy) {
    this.discountPolicy = discountPolicy;
}

 

  • 수정자 메서드(setter)를 통해 선택과 변경가능한 의존관계를 주입하는 방법
  • @Autowired(required = false) 를 통해 선택적으로 주입할 수 있음

필드 주입

@Autowired
private MemberRepository memberRepository;

@Autowired
private DiscountPolicy discountPolicy;

 

  • 필드에서 바로 의존관계를 주입하는 방법
  • 외부 클래스에서 해당 클래스를 사용할때 테스트하기 힘들기 때문에 사용하지 않는 게 좋다
  • 애플리케이션의 실제 코드와 관계 없는 테스트 코드에서만 사용해도 됨

일반 메서드 주입

private MemberRepository memberRepository;
private DiscountPolicy discountPolicy;

@Autowired
public void init(MemberRepository memberRepository, DiscountPolicy discountPolicy) {
    this.memberRepository = memberRepository;
    this.discountPolicy = discountPolicy;
}

 

  • 스프링 빈으로 등록된 클래스의 일반 메소드에 Autowired 붙여서 의존관계를 주입하는 방법
  • 일반적으로 잘 사용하지 않음

Autowired의 required 옵션이나 @Nullable 어노테이션을 사용하여 자동 주입 대상이 없어도 동작하게끔 할 수 있다.

 

과거에는 수정자 주입과 필드 주입을 사용했지만, 최근에는 생성자 주입을 권장한다.

  • 의존 관계를 한 번 설정하고 바꿀 일이 거의 없고 setter를 public으로 열어두면 다른 사람이 사용할 불상사가 일어날 수 있기 때문에 불변하게 설계하는 것이 좋다.
  • 생성자 주입을 사용하면 final 키워드를 사용할 수 있어 오류를 컴파일 시점에 확인할 수 있다. (컴파일 오류가 가장 빠르고 좋은 오류이다)

롬복안에 @Getter, @Setter 등을 사용하여 빠르게 개발할 수 있다.

그 중에 @RequiredArgsConstructor를 사용하면 final이 붙은 필드를 모아서 생성자를 만들어준다. -> 매우 간결

 

@Autowired는 타입으로 조회하기 때문에 동일한 타입이 2개 이상 빈으로 등록되어 있으면 에러가 발생한다.

-> 해결방법

  1. @Autowired 필드명 매칭
  2. @Quilifier를 통해 추가 구분자 사용
  3. @Primary를 통해 우선순위 설정

동일한 타입의 스프링 빈이 여러 개일때 List, Map을 통해서 모두 가져올 수 있다(전략 패턴으로 사용 가능)

private final Map<String, DiscountPolicy> policyMap;
private final List<DiscountPolicy> policies;

 

이미 메뉴얼대로 구현되어 있는 것들은 스프링부트가 제공하는대로 스프링 빈을 자동으로 등록하고

커스텀을 통해서 사용하는 경우에만 수동으로 등록해서 명확하게 드러내도록 한다.

 

 

 

반응형