컴포넌트 스캔

LST·2022년 7월 27일
0

@Bean 을 통해 빈을 등록하는 방법도 있지만 등록해야 할 빈이 여러개라면 반복적인 작업을 해야 할 것이다. 그래서 스프링은 구성 정보가 없어도 자동으로 스프링 빈을 등록하는 컴포넌트 스캔이라는 기능을 제공한다. 그리고 의존관계도 자동으로 주입하는 @Autowired라는 기능도 제공한다.

@Configuration
@ComponentScan
public class AutoAppConfig {
	/* 아무것도 없다*/
}

기존의 DI 컨테이너와는 다르게 @Bean으로 등록한 클래스가 하나도 없다.

컴포넌트 스캔은 이름처럼 @Component 어노테이션이 붙은 클래스를 스캔해서 스프링 빈으로 등록한다. 모든 클래스에 @Component 어노테이션을 붙인다.
@Bean으로 직접 설정 정보를 입력할 땐 의존관계도 직접 작성하였지만, 컴포넌트 스캔을 사용하면 이런 설정 정보가 없기 때문에 @Autowired를 통해 의존관계를 자동으로 주입해주어야 한다.

컴포넌트 스캔과 주입 과정

  1. @ComponentScan
    @ComponentScan은 @Component가 붙은 모든 클래스를 스프링 빈으로 등록한다. 이때 스프링 빈의 기본 이름은 클래스명에서 앞글자만 소문자로 변경한 것이다(ServiceImpl -> serviceImpl). 이름을 직접 지정하고 싶으면 @Component(이름) 으로 부여하면 된다.

  2. 의존관계 자동 주입
    클래스의 생성자에 @Autowired를 지정하면 스프링 컨테이너가 자동으로 해당 스프링 빈을 찾아서 주입한다.

  • 컴포넌트 탐색 위치
    모든 자바 클래스를 컴포넌트 스캔하면 시간이 오래 걸리기 때문에 지정한 위치부터 탐색하도록 시작 위치를 지정할 수 있다.
    @ComponentScan{
        basePackages = "hello.core",
    }
  • 컴포넌트 스캔 대상
    아래 클래스의 소스코드를 보면 @Component를 포함하고 있기 때문에 컴포넌트 스캔의 대상이 된다.
    • @Component : 컴포넌트 스캔에서 사용
    • @Controller : 스프링 MVC 컨트롤러에서 사용
    • @Service : 스프링 비즈니스 로직에서 사용
    • @Repository : 스프링 데이터 접근 계층에서 사용
    • @Configuration : 스프링 설정 정보에서 사용
  • 중복 등록
    컴포넌트 스캔에서 같은 빈 이름을 등록할 경우, 스프링에서는 수동으로 등록한 빈이 자동으로 등록한 빈보다 우선권을 갖는다. (오버라이딩 한다.)
    하지만 스프링 부트에서는 수동 빈 등록과 자동 빈 등록이 충돌하면 오류가 발생한다.

의존관계 주입 방법

의존관계 주입에는 크게 4가지 방법이 있지만 2가지만 사용한다.

생성자 주입

  • 생성자를 통해서 의존관계를 주입 받는다.
  • 생성자 호출시점에 딱 1번만 호출되는 것이 보장된다.
  • 불변, 필수 의존관계에 사용한다.
  • 생성자가 하나만 존재하면 @Autowired는 생략가능하다.
@Component
public class Constructor {
	private final Service num; 
	@Autowired
    public Constructor(Service service){
    	this.num = service
    }
}

수정자 주입

  • setter를 통해서 의존관계를 주입한다.
  • 선택, 변경 가능성이 있는 의존관계에 사용한다.
@Component
public class Setter{
	private final String a;
	@Autowired
    public void setA(String service){
    	this.a = service;
    }
}

생성자 주입과 수정자 주입이 있지만 생성자 주입을 권장한다는데 그 이유는

  • 대부분의 의존관계 주입은 한번 일어나면 어플리케이션 종료까지 바뀌는 일이 거의 없다.
  • 수정자 주입을 사용하면 수정자를 public으로 열어야 하고, 의도치 않게 변경될 수 있다.
  • 생성자 주입을 사용하면 필드에 final 키워드를 사용할 수 있다. 그래서 혹시라도 생성자에서 값이 설정되지 않는 오류를 컴파일 단계에서 발견한다.
  • 프레임워크(스프링)에 의존하지 않고, 순수한 자바 언어의 특징을 살려낸다.

0개의 댓글