패잇 2023. 12. 27. 18:10

AppConfig를 사용하면 설정정보에 직접 등록할 빈을 나열함
→ 빈이 많아지면 일일이 등록하기 귀찮고 설정정보도 커지고 누락하는 문제도 발생.


스프링은 설정정보가 없어도 자동으로 스프링 빈을 등록하는 컴포넌트 스캔 기능과 의존관계도 자동으로 주입하는 @Autowired 기능을 제공한다.

 

컴포넌트 스캔

1. 컴포넌트 스캔을 사용하려면 먼저 @ComponentScan을 설정 정보에 붙여주면 된다.
   컴포넌트 스캔은 이름 그대로 @Component가 붙은 클래스를 스캔해서 스프링 빈으로 등록 한다.
2. 빈으로 등록할 각 클래스가 컴포넌트 스캔의 대상이 되도록 @Component를 붙여준다.

그런데 이렇게만 하면 설정 파일 안에는 아무것도 없음. 그냥 @Component 붙은 애들이 빈으로 등록되는 것
→ 의존관계를 주입해 줄 수 있는 방법이 없다.
그래서 @Autowired로 자동의존관계 주입을 해준다.

 

컴포넌트 스캔을 쓰면 @Autowired를 쓰게 된다. 왜냐면 내 빈이 자동으로 등록되는데 수동으로 설정해 줄 수 있는 곳이 없어서 의존관계를 주입해줄 방법이 없음.
이전에 AppConfig 에서는 @Bean으로 직접 설정정보 작성했고 의존관계로 직접 명시했다. 이제는 이런 설정 정보가 없기 때문에 의존관계 주입도 이 클래스 안에서 해결해야 한다.

 

참고

빈 등록 시 타입이 여러개면(빈 이름 같음) 충돌 난다. 자동등록 시 이름 같은 경우 여러개이거나 자동 등록(@Component), 수동 등록(AppConfig) 으로 중복 등록되면 에러가 발생한다. -> 애초에 빈 이름 같게 애매한 상황을 만들지 마라! 이름 따로 등록하지 말고 되도록 기본값 사용(클래스 이름으로 자동 등록되는 이름)

 

탐색 위치와 기본 스캔 대상

탐색할 패키지의 시작 위치 지정

모든 자바클래스를 다 컴포넌트 스캔하면 시간 오래걸림. 찾을 때 라이브러리까지 다 탐색함.
→ 꼭 필요한 위치부터 탐색하도록 시작 위치를 지정할 수 있다.

@Componentscan( basePackages = "패키지 경로" )


- basePackages : 탐색할 패키지의 시작 위치를 지정. 이 패키지를 포함해서 하위 패키지를 모두 탐색한다.
- basePackageClasses : 지정한 클래스의 패키지를 탐색 시작위치로 지정. 
만약 지정하지 않으면 @ComponentScan이 붙은 설정 정보 클래스의 패키지가 시작 위치가 된다.

 

권장하는 방법
패키지 위치를 지정하지 않고, 설정 정보 클래스의 위치를 프로젝트 최상단에 두는 것. 최근 스트링 부트도 이 방법을 기본으로 제공한다.
참고로 스프링 부트를 사용하면 스프링 부트의 대표 시작 정보인 @SpringBootApplication을 이 프로젝트 시작 루트 위치에 두는 것이 관례. (그리고 이 설정안에 바로 @ComponentScan이 들어 있다! 그래서 스프링 부트 쓰면 @ComponentScan 자체를 쓸 필요가 없다.)

 

컴포넌트 스캔 기본 대상

컴포넌트 스캔은 @Component 뿐만 아니라 @Controller, @Service, @Repository도 추가로 대상에 포함한다.

각 어노테이션 소스를 보면 @Component를 포함하고 있음.

@interface : 그 뒤에 있는 애가 어노테이션이라는 의미. @Controller가 된다는 것.

 

참고

어노테이션에는 상속관계가 없음. 이렇게 어노테이션이 특정 어노테이션을 들고 있는 것을 인식할 수 있는 것은 자바가 지원하는게 아니고 스프링이 지원하는 기능이다.

 

컴포넌트 스캔의 용도 뿐만 아니라 다음 어노테이션이 있으면 스프링은 부가 기능을 수행한다.

@Contoller : 스프링 MVC 컨트롤러로 인식

@Service : 사실 @Service는 특별한 처리 하지 않음. 개발자들이 핵심 비지니스 로직이 여기 있겠구나라고 비지니스 계층을 인식하는데 도움이 된다.