저번 시간까지는 스프링 빈을 등록할 경우 @Bean 어노테이션을 통해서 설정 정보에 직접 등록을 했는데요.
실무에서는 등록해야할 @Bean이 수십, 수백개가 되면서 굉장히 귀찮아집니다. (누락문제도 추가)
그래서 설정 정보 없이도 자동으로 스프링 빈을 등록하는 '컴포넌트 스캔'이라는 기능이 있는데요.
컴포넌트 스캔 기능을 확인하기 위해 기존의 AppConfig를 내버려두고 , AutoAppConfig 파일을 새로 만들었습니다.
(excludeFilters는 이전에 @Configuration이 붙은 AppConfig도 스캔되는 것을 방지하기 위해, 추가한 코드입니다.)
이 코드를 보면 설정 정보 파일인데도 @Bean 어노테이션이 하나도 없습니다.
@ComponentScan 어노테이션이 붙으면 @Configuration이 붙은 설정 정보도 자동으로 등록이 되는데
그 이유는 @ComponentScan 어노테이션을 자세히 들여다 보면,
이 역시도 @Component 어노테이션이 내장되어있기 때문입니다.
그리고 이제 각 클래스가 컴포넌트 스캔의 대상이 되도록 @Component 어노테이션을 붙여줍니다.
이전에는 AppConfig에서 @Bean을 통해 설정 정보도 작성했고, 의존관계도 명시했는데
AutoAppConfig는 그런 설정 정보가 없으므로 의존관계 주입도 클래스 안에서 해결해야 합니다.
이때 @Autowired 어노테이션이 사용됩니다.
-@Autowired는 생성자에서 여러 의존관계를 한 번에 주입받을 수 있습니다. (뒤에 더 자세히 설명)
결과적으로, @ComponentScan을 통해서 @Component가 붙은 모든 클래스를 스프링 빈으로 등록합니다.
-이때 이름은 클래스명을 그대로 사용하지만 맨 앞자리는 소문자로 유지됩니다.
-@Component("memberService2")와 같은 식으로 어노테이션을 붙이면 이름을 직접 지정도 가능합니다.
@Autowired
@Autowired는 의존관계를 자동으로 주입해주는 어노테이션 입니다.
그림과 같이 MemberServiceImpl 클래스의 MemberServiceImpl 생성자 부분에 @Autowired를 붙여주면
스프링 컨테이너가 자동으로 해당 스프링 빈을 찾아서 주입해줍니다.
이는 getBean(MemberRepository.class)와 동일한 방식입니다.
이와 같이, 생성자에 파라미터가 복수여도 다 찾아서 주입시켜줍니다.
참고로, 위 @Component 부분을 보면
이렇게 되어 있는데, 이걸 보고 스프링은 파라미터의 타입을 보고
"아 MemberRepository의 구현체는 MemoryMemberRepository이구나"하고
생성자에서 memberRepository를 불러오면 스프링 빈에서 memoryMemberRepository를 꺼내오는 겁니다.
컴포넌트 스캔 기본 대상
컴포넌트 스캔은 @Component 뿐만 아니라 다른 경우에도 스캔 대상으로 포함합니다.
1.@Component : 컴포넌트 스캔에 당연히 포함
2.@Controller : 스프링 MVC 컨트롤러에서 사용
3.@Service : 스프링 비즈니스 로직에서 사용
4. @Repository: 스프링 데이터 접근 계층에서 사용
5. @Configuration: 스프링 설정 정보에서 사용
이 어노테이션들도 스캔 대상으로 포함되는 이유는 아까 Configuration의 경우에서도 설명한것과 같은 맥락입니다.
모두, 어노테이션을 들여다보면 @Component라는 어노테이션을 포함하고 있습니다.
+useDefaultFilters 옵션이 있는데 이는 기본값으로 켜져 있으며, 이걸 끄면 스캔대상에서 빠진다.
수동 등록 vs 자동 등록
이제 @Component를 통한 자동 빈 등록을 배웠는데, 그렇다면 수동 등록과 자동 등록을 중복으로 사용한다면?
그럴 일은 거의 없겠지만, 만약 자동 빈으로 등록하고 수동으로 빈을 등록하는 방식모두 사용한다면
오류가 발생할 수 있다.
만약 수동으로 이미 존재하는 빈에 추가로, 자동으로 스프링 빈을 등록했는데, 그 이름이 같은 경우 스프링은
`ConflictingBeanDefinitionException`이라는 예외를 발생시킨다.
반대로, 자동 빈 등록 이후에 수동 빈 등록을 시도했는데 이름이 같다면?
결과는 이 경우 수동 빈 등록이 우선권을 가진다. (수동 빈이 자동 빈을 오버라이딩 해버린다.)
'스프링' 카테고리의 다른 글
스프링 기초 - 빈 생명주기 콜백 (0) | 2024.02.19 |
---|---|
스프링 기초 - 의존관계 주입 (0) | 2024.02.15 |
스프링 기초 - 싱글톤 컨테이너 (0) | 2024.02.14 |
스프링 기초 - 스프링 컨테이너 (0) | 2024.02.14 |
스프링 기초 - 스프링으로 전환 (0) | 2024.02.13 |