ComponentScan이란?
@Component 어노테이션을 사용한 클래스들을 스프링빈으로 등록하기 위해서,
그 범위를 정하는 상위 어노테이션이다.
AppConfig.java에 @Configuration과 @Bean을 통해 스프링 컨테이너에 싱글톤으로 객체를 등록을 했다.
하지만, 객체를 만들게 많아질 수록 코드는 길어진다.
이건 번거로운 일이다.
그래서 빌드가 될때 자동으로 스프링빈을 등록해주는 방법이 있는데,
그게 @ComponentScan을 통해서 할 수 있다.
또, 뒤에서 공부하겠지만 @Autowired라는 기능도 제공받아 의존관계 주입을 받을 수 있다.
AutoAppConfig.java
package hello.core;
@Configuration
@Componentscan
public class AutoAppConfig{
}
AppConfig에서는 @Bean을 사용하였지만 현재 AutoAppConfig는 사용하지 않는다.
@ComponentScan은 해당 어노테이션을 적용한 클래스 패키지를 포함한 하위에 있는
@Component 어노테이션을 적용한 클래스들을 스캔하여 모두 스프링 컨테이너에 등록을 해준다.
@Configuration도 컴포넌트 스캔의 대상인 이유는 소스코드를 열면 @Component 어노테이션이 적용되어있다.
이전 AppConfig에서는 직접 @Bean 정보를 입력을 했지만, 현재는 @Component를 적용한 클래스에 직접 의존관계를 주입해야한다.
이 후에 공부 하겠지만, @Autowired하는 방법은 여러가지가 있다.
그 중 생성자로 주입받을때 여러 의존관계를 한번에 주입 가능하다.
@ComponentScan과 의존관계의 주입방식을 디테일하게 알아보자
@ComponentScan은 위에서 설명한 것과 같이 해당 클래스 파일이 속한 패키지를 포함한 하위의 패키지들에서
@Component가 붙은 클래스들을 모두 스캔하여 스프링빈으로 생성을 해준다.
그때 스프링 빈의 기본 이름으로 클래스명을 사용하지만 맨 앞의 글자는 소문자로 사용한다
→ public class MemberService 클래스라면 스프링 빈의 이름으로는 memberService가 되는 것이다.
하지만 내가 이름을 정해줄 수 있다.
@Component("memberService1")
public class MemberService{}
이 방법은 추후 혼란을 야기할 수 있어 좋지 않다.
그러하여 @Component로 스프링빈이 등록이 된다면, @Autowired로 의존관계를 주입 받을 수 있다.
@Component
public class MemberServiceImpl{
private MemberService memberService;
@Autowired
public MemberServiceImpl(MemberService memberSerivce){
this.memberService= memberService
}
}
@ComponentScan의 스캔 범위는 위에서 설명해서 넘어가도록 하겠다.
하지만, 개발자의 설정을 통해서 스캔범위를 지정해줄 수 있다.
@ComponentScan(
basePackages = "hello.core" //1
basePackages = {"hello.core", "hello.service"} //2
basePackageClasses = AutoAppConfig.class //3
)
위와 같이 설정을 통하여 범위를 지정 가능하며,
1. hello.core를 포함한 패키지 하위 패키지를 스캔하라이다.
2. 여러개도 가능하다.
3. AutoAppConfig가 있는 위치를 포함한 하위 패키지들을 스캔하라.
설정을 안하면 3번이 default로 설정이 된다. ( 권장 )
중복등록으로 인한 충돌
컴포넌트 스캔을 통하여 스프링빈을 만들때 같은 이름의 스프링빈이 등록되려하면, 수동으로 스프링빈의 이름을 주는게 명확하다보니 수동으로 등록한 스프링빈이 등록이 되며, 아래와 같은 문구를 남긴다.
Overriding bean definition for bean 'memoryMemberRepository' with a different
definition: replacing
수동으로 이름을 정한것이 나쁘다곤 할 수는 없지만 추후에 문제를 야기할 수 있어서 좋은 방법은 아니다.
그래서 스프링부트에서는 이런 상황에는 에러를 내주며,
혹시라도 수동등록이 필요한 경우 application.properties에서
spring.main.allow-bean-definition-overriding=true 와 같이 설정이 가능하다.
'공부 > 과거 자료' 카테고리의 다른 글
[Java] 클래스메서드, 인스턴스메서드 (0) | 2022.07.14 |
---|---|
[Spring] 의존관계 자동 주입 (0) | 2022.07.14 |
[Spring] 싱글톤 (0) | 2022.07.13 |
[Spring] @Configuration, @Bean, Application (0) | 2022.07.13 |
[Spring] DI 란 (0) | 2022.07.13 |